I have been looking at a lot of different C# encryption examples. In most examples the encryption Key as well as the Initialization Vector (IV) are passed into the encryption/decryption methods as an array of bytes.
I would like to store the Key and IV as strings. The Key in a Hardware Security Module and the IV as an nvarchar in the SQL Server database.
I keep running into propblems on how to properly convert the Key and the IV as string. Some examples say to use Base64 Encoding while other examples use Encoding.UTF8
.
Here is an example that generates an IV and converts it to a Base64 string...
using (var aesProvider = new AesCryptoServiceProvider())
{
aesProvider.GenerateIV();
var ivBase64 = Convert.ToBase64String(aesProvider.IV);
return ivBase64;
}
However, when I pass this string representation of the IV into the encryption method and then convert it back to a byte array the following code fails saying the IV is not the proper size.
byte[] initVectorBytes = Encoding.UTF8.GetBytes(initializationVector);`
// intermediate code excluded for brevity
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
Is there a standard way of converting an encryption Key and IV back and forth between a byte array and String representation?
An initialization vector (IV) is an arbitrary number that can be used with a secret key for data encryption to foil cyber attacks. This number, also called a nonce (number used once), is employed only one time in any session to prevent unauthorized decryption of the message by a suspicious or malicious actor.
Symmetric, or secret key encryption, uses a single key for both encryption and decryption. Symmetric key encryption is used for encrypting large amounts of data efficiently. 256-bit AES keys are symmetric keys. Asymmetric, or public/private encryption, uses a pair of keys.
Public Key: this key is primarily used to encrypt the data and can be freely given as it will be used to encrypt data, not decrypt it. Private Key: this key is used to decrypt the data that it's counterpart, the public key, has encrypted.
For AES encryption: SecretKeyFactory factory = SecretKeyFactory. getInstance("PBKDF2WithHmacSHA1"); KeySpec spec = new PBEKeySpec(password, salt, 65536, 256); SecretKey tmp = factory. generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.
You cannot convert binary data to UTF-8 and back again. Some binary sequences are not valid UTF-8 characters and when you convert to UTF-8 that data is lost. It's the equivalent of some characters getting set to '?' when converting between encodings.
You can instead use base64 encoding of binary data to text, and then base64 decode to get back the original binary.
Try converting this to UTF-8, for example: "\x00?\xdc\x80" (that's four bytes: 0, 63, 220, 128). It won't encode to UTF-8 -- it's not valid.
The standard way is using Base-64 encoding - How do I encode and decode a base64 string?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With