Как использовать 'System.Security.Cryptography.AesManaged' для шифрования байта []?

eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0

не является допустимой строкой в ​​кодировке Base64, потому что ее длина не кратная 4. Некоторые декодеры Base64 допускают эту ошибку, но методы NSData этого не делают.

Итак, это на самом деле ошибка на стороне сервера, создающая строчную кодировку Base64. Если это необходимо, вы можете исправить его в своем приложении, добавив требуемое дополнение с символами = (код обновлен для Swift 2):

var base64String = arr[1] as String
if base64String.characters.count % 4 != 0 {
    let padlen = 4 - base64String.characters.count % 4
    base64String += String(count: padlen, repeatedValue: Character("="))
}

И теперь декодирование работает как ожидалось:

if let data = NSData(base64EncodedString: base64String, options: []),
    let str = String(data: data, encoding: NSUTF8StringEncoding) {
    print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"}
}

Swift 4:

var base64String = "eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0"

if base64String.count % 4 != 0 {
    let padlen = 4 - base64String.count % 4
    base64String.append(contentsOf: repeatElement("=", count: padlen))
}

if let data = Data(base64Encoded: base64String) ,
    let str = String(data: data, encoding: .utf8) {
    print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"}
}
13
задан Chris 9 June 2009 в 12:33
поделиться

3 ответа

РЕДАКТИРОВАТЬ: заметил правку eed3si9n ... Я согласен, симметричное шифрование - плохой выбор для паролей. Вместо этого используйте хэши (и , а не MD5). Вот очень полный пример .

Простой пример:

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

Чтобы проверить правильный пароль, вы должны выполнить то же вычисление над предоставленным паролем и сравнить результат с хешем, который есть в вашем база данных.

Хорошей практикой является добавление соли (случайных данных) к открытому тексту, чтобы избежать атак на радужную таблицу . Обычно перед хешированием к незашифрованному тексту добавляется известное случайно сгенерированное значение, уникальное для данного пользователя.

12
ответ дан 1 December 2019 в 19:41
поделиться

Вот что я в итоге сделал, вдохновленный (более старой версией) ответа Майкла:

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();
}
12
ответ дан 1 December 2019 в 19:41
поделиться

Простое шифрование и дешифрование данных в C # .

Изменить : для паролей я бы рекомендовал использовать BCrypt вместо двустороннего шифрование, если вам действительно не нужно восстанавливать исходный пароль. Обычно вам достаточно того, что кто-то знает пароль, а не сам пароль.

8
ответ дан 1 December 2019 в 19:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: