예제 #1
0
        public override EncryptResult Encrypt(EncryptOptions options, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNull(options, nameof(options));

            ThrowIfTimeInvalid();

            EncryptionAlgorithm algorithm = options.Algorithm;

            if (algorithm.GetAesCbcEncryptionAlgorithm() is AesCbc aesCbc)
            {
                // Make sure the IV is initialized.
                options.Initialize();

                using ICryptoTransform encryptor = aesCbc.CreateEncryptor(KeyMaterial.K, options.Iv);

                byte[] plaintext  = options.Plaintext;
                byte[] ciphertext = encryptor.TransformFinalBlock(plaintext, 0, plaintext.Length);

                return(new EncryptResult
                {
                    Algorithm = algorithm,
                    KeyId = KeyMaterial.Id,
                    Ciphertext = ciphertext,
                    Iv = options.Iv,
                });
            }
            else if (algorithm.IsAesGcm() && AesGcmProxy.TryCreate(KeyMaterial.K, out AesGcmProxy aesGcm))
            {
                using (aesGcm)
                {
                    byte[] plaintext  = options.Plaintext;
                    byte[] ciphertext = new byte[plaintext.Length];
                    byte[] tag        = new byte[AesGcmProxy.NonceByteSize];

                    // Generate an nonce only for local AES-GCM; Managed HSM will do it service-side and err if serialized.
                    byte[] iv = Crypto.GenerateIv(AesGcmProxy.NonceByteSize);

                    aesGcm.Encrypt(iv, plaintext, ciphertext, tag, options.AdditionalAuthenticatedData);

                    return(new EncryptResult
                    {
                        Algorithm = algorithm,
                        KeyId = KeyMaterial.Id,
                        Ciphertext = ciphertext,
                        Iv = iv,
                        AuthenticationTag = tag,
                        AdditionalAuthenticatedData = options.AdditionalAuthenticatedData,
                    });
                }
            }
            else
            {
                KeysEventSource.Singleton.AlgorithmNotSupported(nameof(Encrypt), algorithm);
                return(null);
            }
        }
예제 #2
0
        public override DecryptResult Decrypt(DecryptOptions options, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNull(options, nameof(options));

            ThrowIfTimeInvalid();

            EncryptionAlgorithm algorithm = options.Algorithm;

            if (algorithm.GetAesCbcEncryptionAlgorithm() is AesCbc aesCbc)
            {
                using ICryptoTransform decryptor = aesCbc.CreateDecryptor(KeyMaterial.K, options.Iv);

                byte[] ciphertext = options.Ciphertext;
                byte[] plaintext  = decryptor.TransformFinalBlock(ciphertext, 0, ciphertext.Length);

                return(new DecryptResult
                {
                    Algorithm = algorithm,
                    KeyId = KeyMaterial.Id,
                    Plaintext = plaintext,
                });
            }
            else if (algorithm.IsAesGcm() && AesGcmProxy.TryCreate(KeyMaterial.K, out AesGcmProxy aesGcm))
            {
                using (aesGcm)
                {
                    byte[] ciphertext = options.Ciphertext;
                    byte[] plaintext  = new byte[ciphertext.Length];

                    aesGcm.Decrypt(options.Iv, ciphertext, options.AuthenticationTag, plaintext, options.AdditionalAuthenticatedData);

                    return(new DecryptResult
                    {
                        Algorithm = algorithm,
                        KeyId = KeyMaterial.Id,
                        Plaintext = plaintext,
                    });
                }
            }
            else
            {
                KeysEventSource.Singleton.AlgorithmNotSupported(nameof(Decrypt), algorithm);
                return(null);
            }
        }