public void TestChallenge18() { var encrypted = Convert.FromBase64String(Set3Data.Challenge18Input); var keyStr = "YELLOW SUBMARINE"; var key = System.Text.Encoding.ASCII.GetBytes(keyStr); ulong nonce = 0; var decrypted = AesCtr.Decrypt(key, nonce, encrypted); var actual = System.Text.Encoding.ASCII.GetString(decrypted); Assert.AreEqual(Set3Data.Challenge18Solution, actual); // Encrypt and verify against input data var enc = AesCtr.Encrypt(key, nonce, decrypted); CollectionAssert.AreEqual(encrypted, enc); }
public void Aes128CtrDecrypt(string plainString, string encryptedHexString) { // Obtain the key. byte[] key = "7b6dcbffad4bbbcd25e2a80201739233".HexToBytes(); // Obtain the data as bytes. byte[] encryptedData = encryptedHexString.HexToBytes(); // Decrypt the provided data. byte[] resultData = AesCtr.Decrypt(key, encryptedData, null); string resultString = Encoding.UTF8.GetString(resultData); // Assert the data is the same length Assert.Equal(plainString.Length, resultString.Length); // Verify the string equals the original string. Assert.Equal(plainString, resultString); }
public void Aes192CtrEncryptDecrypt(string testString) { // Generate a random key. byte[] key = new byte[24]; // 192 bit RandomNumberGenerator random = RandomNumberGenerator.Create(); random.GetBytes(key); // Obtain the data as bytes. byte[] testData = Encoding.UTF8.GetBytes(testString); // Encrypt then decrypt the data. byte[] encrypted = AesCtr.Encrypt(key, testData); byte[] decrypted = AesCtr.Decrypt(key, encrypted); // Get the decrypted result as a string string result = Encoding.UTF8.GetString(decrypted); // Verify the string equals the original string. Assert.Equal(testString, result); }
[InlineData("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", "601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c52b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6")] // AES-256-CTR public void AesCtrTestWithNISTVectors(string keyHexString, string counterHexString, string plainTextHexString, string cipherTextHexString) { // Obtain the components as bytes. byte[] key = keyHexString.HexToBytes(); byte[] counter = counterHexString.HexToBytes(); byte[] plainTextData = plainTextHexString.HexToBytes(); // Encrypt the provided data. byte[] encryptedData = AesCtr.Encrypt(key, plainTextData, counter); string encryptedDataHexString = encryptedData.ToHexString(false); // Assert this equals our ciphered text Assert.Equal(cipherTextHexString, encryptedDataHexString, true); // Decrypt the data back to it's original format byte[] decryptedData = AesCtr.Decrypt(key, encryptedData, counter); string decryptedDataHexString = decryptedData.ToHexString(false); // Assert this equals our plain text Assert.Equal(plainTextHexString, decryptedDataHexString, true); }
public static byte[] Decrypt(EthereumEcdsa localPrivateKey, Memory <byte> message, Memory <byte> sharedMacData) { // Verify our provided key type if (localPrivateKey.KeyType != EthereumEcdsaKeyType.Private) { throw new ArgumentException("ECIES could not decrypt data because the provided key was not a private key."); } // Verify the size of our message (layout specified in Encrypt() describes this value) if (message.Length <= ECIES_ADDITIONAL_OVERHEAD) { throw new ArgumentException("ECIES could not decrypt data because the provided data did not contain enough information."); } // Verify the first byte of our data int offset = 0; if (message.Span[offset++] != ECIES_HEADER_BYTE) { throw new ArgumentException("ECIES could not decrypt data because the provided data had an invalid header."); } // Extract the sender's public key from the data. Memory <byte> remotePublicKeyData = message.Slice(offset, 64); EthereumEcdsa remotePublicKey = EthereumEcdsa.Create(remotePublicKeyData, EthereumEcdsaKeyType.Public); offset += remotePublicKeyData.Length; Memory <byte> counter = message.Slice(offset, AesCtr.BLOCK_SIZE); offset += counter.Length; Memory <byte> encryptedData = message.Slice(offset, message.Length - offset - 32); offset += encryptedData.Length; byte[] tag = message.Slice(offset, message.Length - offset).ToArray(); offset += tag.Length; // Generate the elliptic curve diffie hellman ("ECDH") shared key byte[] ecdhKey = localPrivateKey.ComputeECDHKey(remotePublicKey); // Perform NIST SP 800-56 Concatenation Key Derivation Function ("KDF") Memory <byte> keyData = DeriveKeyKDF(ecdhKey, 32); // Split the AES encryption key and MAC from the derived key data. var aesKey = keyData.Slice(0, 16).ToArray(); byte[] hmacSha256Key = keyData.Slice(16, 16).ToArray(); hmacSha256Key = _sha256.ComputeHash(hmacSha256Key); // Next we'll want to verify our tag (HMACSHA256 hash of counter + encrypted data + shared mac data). // We copy the data into a buffer for this hash computation since counter + encrypted data are already aligned. byte[] tagPreimage = new byte[counter.Length + encryptedData.Length + sharedMacData.Length]; Memory <byte> tagPreimageMemory = tagPreimage; counter.CopyTo(tagPreimageMemory); encryptedData.CopyTo(tagPreimageMemory.Slice(counter.Length, encryptedData.Length)); sharedMacData.CopyTo(tagPreimageMemory.Slice(counter.Length + encryptedData.Length)); // Obtain a HMACSHA256 provider HMACSHA256 hmacSha256 = new HMACSHA256(hmacSha256Key); // Compute a hash of our counter + encrypted data + shared mac data. byte[] validTag = hmacSha256.ComputeHash(tagPreimage); // Verify our tag is valid if (!tag.SequenceEqual(validTag)) { throw new ArgumentException("ECIES could not decrypt data because the hash/tag on the counter/encrypted data/shared mac data was invalid."); } // Decrypt the data accordingly. byte[] decryptedData = AesCtr.Decrypt(aesKey, encryptedData.ToArray(), counter.ToArray()); // Return the decrypted data. return(decryptedData); }