google-cloud-kms Синтаксис криптографических сообщений PKCS7 - PullRequest
0 голосов
/ 11 февраля 2019

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

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

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

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

ПРИМЕЧАНИЕ: Iя не программист 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();
        }
    }
}
0 голосов
/ 12 февраля 2019

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

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

...