#c# #encryption #aes #cryptojs
Вопрос:
Я также немного запутался в различиях между C# и CryptoJS.у меня есть две серверные функции для шифрования данных с помощью AES256 бит следующим образом;
public string EncryptText_PBKDF2(string input, string password)
{
// Get the bytes of the strings
byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
// Hash the password with SHA256 for AES key
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesEncrypted = AES_Encrypt_PBKDF2(bytesToBeEncrypted, passwordBytes);
string result = Convert.ToBase64String(bytesEncrypted);
return resu<
}
private byte[] AES_Encrypt_PBKDF2(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
using (MemoryStream ms = new MemoryStream())
{
aes.KeySize = 256;
aes.BlockSize = 128;
aes.IV = MD5.Create().ComputeHash(passwordBytes);//16 byte
var PBKDF2_key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
aes.Key = PBKDF2_key.GetBytes(aes.KeySize / 8);//32 byte
aes.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, aes.CreateEncryptor(aes.Key, aes.IV), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
return encryptedBytes;
}
затем я отправляю его на просмотр с помощью действия контроллера;
string res = aesIsl.EncryptText_PBKDF2("my text", "my key");
ViewBag.Crypted1 = res;
на стороне клиента я получаю его из скрытого поля
<div id="crypted"><input id="hidden1" data-enc="@ViewBag.Crypted1" type="hidden" /></div>
и расшифруйте его с помощью библиотеки crypto-js(у меня есть 4 попытки, указанные поверх них)
вот моя функция расшифровки и попытки:
function AesleDesifrele_PBKDF2(ciphertext, pwd) {
var salt = "0000000000000000";
var iv = CryptoJS.MD5(CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pwd)));
//these are my attempts to decrypt
//ATTEMPT #1:
//returning object contains a word array but converting it to utf8 string
//causes "Malformed UTF-8 data" error
console.log(CryptoJS.AES.decrypt(ciphertext, pwd).toString(CryptoJS.enc.Utf8));
//ATTEMPT #2
var key = CryptoJS.PBKDF2(
CryptoJS.enc.Utf8.parse(pwd).toString(CryptoJS.enc.Utf8),
CryptoJS.enc.Hex.parse(salt),
{ keySize: 128 / 32, iterations: 1000 }
);
var decrypted = CryptoJS.AES.decrypt(
ciphertext,
key,
{ iv: iv }
);
//returning object contains a word array but converting it to utf8 string
//causes "Malformed UTF-8 data" error
console.log(decrypted.toString(CryptoJS.enc.Utf8));
//ATTEMPT #3
var raw = base64UrlDecode(ciphertext);
var iv1 = CryptoJS.lib.WordArray.create(CryptoJS.MD5(CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pwd))));;
var salt1 = CryptoJS.lib.WordArray.create(CryptoJS.enc.Hex.parse(salt));
var key1 = generateKey(pwd, salt1);
var ciphertextWords = CryptoJS.lib.WordArray.create(raw.words.slice(128 / 32 128 / 32));
var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: ciphertextWords });
var plaintextArray = CryptoJS.AES.decrypt(
cipherParams,
key1,
{ iv: iv1 }
);
console.log(CryptoJS.enc.Utf8.stringify(plaintextArray));
//returning object contains a word array but converting it to utf8 string
//returns nothing
//ATTEMPT #4
var iv2 = CryptoJS.MD5(CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pwd)));
var Pass = CryptoJS.enc.Utf8.parse(pwd);
var Salt = CryptoJS.enc.Utf8.parse(salt);
var key256Bits1000Iterations = CryptoJS.PBKDF2(Pass.toString(CryptoJS.enc.Utf8), Salt, { keySize: 256 / 32, iterations: 1000 });
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
});
var decrypted = CryptoJS.AES.decrypt(cipherParams, key256Bits1000Iterations, { mode: CryptoJS.mode.CBC, iv: iv2, padding: CryptoJS.pad.Pkcs7 });
console.log(decrypted.toString(CryptoJS.enc.Utf8));
//returning object contains a word array but converting it to utf8 string
//returns nothing
}
это функция для генерации ключа для расшифровки CryptoJS
function generateKey(secret, salt) {
return CryptoJS.PBKDF2(
secret,
salt,
{
keySize: this.keySize / 32, // size in Words
iterations: 1000,
hasher: CryptoJS.algo.SHA256
}
);
}
это функция преобразования, которую я использую
function base64UrlDecode(str) {
return CryptoJS.enc.Base64.parse(str.replace(/-/g, ' ').replace(/_/g, '/'));
}
несмотря на то,что я контролирую параметры на клиенте(зашифрованный текст,пароль,IV и соль) точно так же, как и на сервере, CryptoJS.decrypt ничего не возвращает без каких-либо ошибок.я думаю, мне не хватает преобразования чего-либо в другое, чтобы C# был совместим с CryptoJS.
любые советы приветствуются.
заранее спасибо.
Комментарии:
1. Если у вас нет особых требований использовать эти алгоритмы именно таким образом и никак иначе, я бы рекомендовал libsodium-он имеет привязки C# и JS и гораздо более простой интерфейс.
2. Для меня это слишком похоже на случайную попытку. Первое, что бросается в глаза,-это то, что вы, похоже, только предварительно хэшируете пароль (а не только IV) в C#, используя SHA-256. Тем не менее, я бы поддержал комментарий Йеруна (Хой Йерун) о том, что изобретать свою собственную схему было бы очень плохой идеей, потому что я бы полностью разрушил ее за считанные секунды, даже если вы используете AES. Кстати, способ отладки крипто кода состоит в том, чтобы распечатать все промежуточные значения (IV ключа и т. Д.) В шестнадцатеричных числах, а затем искать различия между приложениями. Ваш код с обеих сторон должен быть СИММЕТРИЧНЫМ, как и шифр
3. спасибо, Джерун. я проверю это.также спасибо тебе, Мартен, за твою comment.as вы заметили, что я хэшировал pwd в C#, используя sha-256, чтобы подготовить его к использованию AES256.также я хэшировал этот хэшированный pwd в c#, используя md5, потому что я использую один и тот же pwd(совместно используемый с обменом ключами диффи-Хеллмана), и я хэшировал его с помощью md5, чтобы использовать его в качестве IV на стороне JS.я зарегистрировал значения обеих сторон путем их хэширования. все значения одинаковы.я думаю,что мне нужно выполнить некоторое преобразование для библиотеки crypto-js, но я не смог найти, какое из них и как.большое вам спасибо за ваше время.