How to use 'System.Security.Cryptography.AesManaged' to encrypt a byte[]?

99封情书 提交于 2019-11-27 03:16:59

问题


Basically i want to use System.Security.Cryptography.AesManaged (or a better class, if you think there is one?) to take one byte array and create another encrypted byte array, using a given symmetric key (i assume i'll need one?).

I also will need the way to reverse this procedure.

The point of this is so i can encrypt stored passwords. I assume there's a simple way to do this?

Thanks


回答1:


EDIT: Noticed eed3si9n's edit... I agree, symmetric encryption is a bad choice for passwords. Use hashes (and not MD5) instead. Here's a very complete example.

A simple example:

byte[] clear = GetCleartext();
HashAlgorithm sha2 = SHA256CryptoServiceProvider.Create();
byte[] hashed = sha2.ComputeHash(clear);

To validate a correct password, you would run the same computation over the provided password, and compare the result to the hash you have in your database.

It's good practice to add salt (random data) to the cleartext to avoid rainbow table attacks. Basically, append a known randomly-generated value, unique to that user, to the cleartext before hashing.




回答2:


Here's what i did in the end, inspired by (an older version of) michael's answer:

private string Encrypt(string input)
{
  return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(input)));
}
private byte[] Encrypt(byte[] input)
{
  PasswordDeriveBytes pdb = new PasswordDeriveBytes("hjiweykaksd", new byte[] { 0x43, 0x87, 0x23, 0x72, 0x45, 0x56, 0x68, 0x14, 0x62, 0x84 });
  MemoryStream ms = new MemoryStream();
  Aes aes = new AesManaged();
  aes.Key = pdb.GetBytes(aes.KeySize / 8);
  aes.IV = pdb.GetBytes(aes.BlockSize / 8);
  CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);
  cs.Write(input, 0, input.Length);
  cs.Close();
  return ms.ToArray();
}
private string Decrypt(string input)
{
  return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(input)));
}
private byte[] Decrypt(byte[] input)
{
  PasswordDeriveBytes pdb = new PasswordDeriveBytes("hjiweykaksd", new byte[] { 0x43, 0x87, 0x23, 0x72, 0x45, 0x56, 0x68, 0x14, 0x62, 0x84 });
  MemoryStream ms = new MemoryStream();
  Aes aes = new AesManaged();
  aes.Key = pdb.GetBytes(aes.KeySize / 8);
  aes.IV = pdb.GetBytes(aes.BlockSize / 8);
  CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write);
  cs.Write(input, 0, input.Length);
  cs.Close();
  return ms.ToArray();
}



回答3:


Simple encrypting and decrypting data in C#.

Edit: For passwords, I would recommend using BCrypt instead of doing a two-way encryption, unless you really need to recover the original password. Normally you just need the fact that someone knew the password, not the password itself.




回答4:


There is a pretty nice C# implementation of symmetric key encryption at http://www.superstarcoders.com/blogs/posts/symmetric-encryption-in-c-sharp.aspx . It supports AES, Triple DES, and Rijndael. It has easy to follow functions in the form:

 string Encrypt(string plaintext, string password, string salt)



回答5:


The OP states they have to pass the credentials to another service, which is a completely different issue than password storage and verification.

Depending on how much control you have over the partner service, or what they expose, the best solutions involve a vendor provided or industry standard approaches such as Kerberos, SAML or other stable, secure bearer token means to flow trust. This is a deep topic.

But let's assume you need to pass credentials via Basic Auth SSL/TLS. So now you need to store them securely in a reversible manner. To solve this problem, I have had success with the secret key being conveyed using a certificate private key. This affords some protection of your secret by the operating system and allows for OPS folks to manage the keys, which is desirable. The account used to run your process must be granted rights to see the private key, which then terminates the trust chain at the OS.

You still might have to think about key rotation, which will require you to store a version number with the cipher text.

Also, SecureString might be of interest, but until all .NET API's allow SecureString to be passed as part of a credential, often times you end up with a string on the managed heap you cannot destroy.

Anyway, this isn't a spoon fed answer with code, but from experience, I have found that managing the chain of secrets is always a problem, and if you cannot terminate at a hardened infrastructure such as Active Directory, certificates are the next best thing.



来源:https://stackoverflow.com/questions/967773/how-to-use-system-security-cryptography-aesmanaged-to-encrypt-a-byte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!