google-cloud-kms PKCS7 Синтаксис криптографических сообщений

Кто-нибудь внедрил Синтаксис криптографических сообщений, используя сервис Google HSM и KMS?

Трудно сказать, встроена ли эта функциональность в библиотеку Tink или нет.

Нет движка Google для OpenSSL или BoringSSL (хотелось бы, чтобы его исправили, если не так), и так как движок нужно писать на clang, я думаю, довольно сложно включить библиотеку tink.so?

Если у кого-либо есть какая-либо информация о выполнении этих типов операций в службе Google KMS, это будет с благодарностью.

1 ответ

В настоящее время для этого потребуется значительное количество пользовательского кода, хотя это технически возможно. Эта функциональность не встроена в Tink, а также не доступен движок Cloud KMS для OpenSSL или BoringSSL.

Вероятно, самым простым способом было бы использовать Java-клиент Cloud KMS с поддержкой CMS в Bouncycastle, хотя я не уверен, является ли Java вариантом для вашего варианта использования. Я мог бы написать пример того, как это сделать, если вы думаете, что это будет полезно.

Спасибо за направление @bdhess!

Я предоставил некоторые фрагменты кода для тех, кто заинтересован в попытках подобной функциональности. Основной класс, чтобы отметить это ContentSignerFactory.java Здесь происходит волшебство API.

Существует очень полезный PDF для Bouncycastle: https://www.bouncycastle.org/fips-java/BCFipsIn100.pdf

ПРИМЕЧАНИЕ: я не программист Java

Cms.java

public class Cms {
    public static byte[] signDataKms(
            String credentialsKeyPath,
            String keyName,
            X509Certificate signingCert,
            byte data[]) throws Exception {

        List<X509Certificate> certList = new ArrayList<>();
        certList.add(signingCert);
        Store certs = new JcaCertStore(certList);

        CMSTypedData cmsData = new CMSProcessableByteArray(data);

        DigestCalculatorProvider digProvider =
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build();
        JcaSignerInfoGeneratorBuilder signerInfoGeneratorBuilder =
                new JcaSignerInfoGeneratorBuilder(digProvider);

        //SignedHash is a base64-encoded PKCS1 block.
        ContentSigner sha1Signer = ContentSignerFactory.getContentSigner((stream) -> {
            try {
                return Kms.signAsymmetric(credentialsKeyPath, keyName, stream.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return new byte[0];
        }, "SHA256WITHRSA");

        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();

        gen.addSignerInfoGenerator(signerInfoGeneratorBuilder.build(sha1Signer, signingCert));
        gen.addCertificates(certs);
        CMSSignedData cms = gen.generate(cmsData, true);

        return cms.toASN1Structure().getEncoded(ASN1Encoding.DER);
    }
}

ContentSignerFactory.java

public class ContentSignerFactory {

    public static ContentSigner getContentSigner(Function<ByteArrayOutputStream, byte[]> lambda, String algorithm) {
        return new ContentSigner() {
            //This is to ensure that signature is created using the right data.
            ByteArrayOutputStream stream = new ByteArrayOutputStream();

            @Override
            public byte[] getSignature() {
                //Calling HSM here instead, the stream is the AttributeMap
                byte[] data = lambda.apply(stream);
                return data;
            }

            //Perhaps called by BouncyCastle library to provide the content
            @Override
            public OutputStream getOutputStream() {
                return stream;
            }

            @Override
            public AlgorithmIdentifier getAlgorithmIdentifier() {
                return new DefaultSignatureAlgorithmIdentifierFinder().find(algorithm);
            }
        };
    }
}

Kms.java

public class Kms {
    public static byte[] signAsymmetric(String credentialsKeyPath, String keyName, byte[] message)
            throws IOException, NoSuchAlgorithmException {
        // Create the Cloud KMS client.
        try (KeyManagementServiceClient client
                     = KeyManagementServiceClient.create(getKeyManagementServiceSettings(credentialsKeyPath))) {

            // Note: some key algorithms will require a different hash function
            // For example, EC_SIGN_P384_SHA384 requires SHA-384
            byte[] messageHash = MessageDigest.getInstance("SHA-256").digest(message);

            AsymmetricSignRequest request = AsymmetricSignRequest.newBuilder()
                    .setName(keyName)
                    .setDigest(Digest.newBuilder().setSha256(ByteString.copyFrom(messageHash)))
                    .build();

            AsymmetricSignResponse response = client.asymmetricSign(request);
            return response.getSignature().toByteArray();
        }
    }
}
Другие вопросы по тегам