Совместимое шифрование и дешифрование AES для C# и javascript. ⇐ C#
Совместимое шифрование и дешифрование AES для C# и javascript.
Я пытаюсь написать два класса на C# и Javascript, которые я могу использовать в своем проекте для шифрования или дешифрования данных с использованием AES при обмене данными.
Используя AES, я встраиваю Salt (32 байта) и IV (16 байт) в зашифрованный результат, при тестировании это отлично работает для обоих классов по отдельности. Добавление Salt и IV в этот микс не приведет к появлению большого количества ссылок на то, чтобы это работало между двумя платформами.
Для C# я использую стандартный System.Security.Crypthography.AES
Private static readonly int iterations = 1000; публичная статическая строка Encrypt (строковый ввод, строковый пароль) { байт[] зашифрован; байт[] IV; байт[] Соль = GetSalt(); byte[] Key = CreateKey(пароль, Salt); используя (Aes aesAlg = Aes.Create()) { aesAlg.Key = Ключ; aesAlg.Padding = PaddingMode.PKCS7; aesAlg.Mode = CipherMode.CBC; aesAlg.GenerateIV(); IV = aesAlg.IV; var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); используя (var msEncrypt = новый MemoryStream()) { используя (var csEncrypt = новый CryptoStream(msEncrypt, шифратор, CryptoStreamMode.Write)) { используя (var swEncrypt = новый StreamWriter(csEncrypt)) { swEncrypt.Write(вход); } зашифровано = msEncrypt.ToArray(); } } } байт[]комбинированныйIvSaltCt = новый байт[Salt.Length + IV.Length + зашифрованный.Length]; Array.Copy(Salt, 0, CombinedIvSaltCt, 0, Salt.Length); Array.Copy(IV, 0,комбинированныйIvSaltCt, Salt.Length, IV.Length); Array.Copy(зашифровано, 0, комбинированноеIvSaltCt, Salt.Length + IV.Length, зашифровано.Length); return Convert.ToBase64String(combinedIvSaltCt.ToArray()); } общедоступная статическая строка Расшифровать (строковый ввод, строковый пароль) { байт [] inputAsByteArray; строка открытого текста = ноль; пытаться { inputAsByteArray = Convert.FromBase64String(вход); байт[] Соль = новый байт[32]; байт[] IV = новый байт[16]; байт[] Закодированный = новый байт[inputAsByteArray.Length - Salt.Length - IV.Length]; Array.Copy(inputAsByteArray, 0, Salt, 0, Salt.Length); Array.Copy(inputAsByteArray, Salt.Length, IV, 0, IV.Length); Array.Copy(inputAsByteArray, Salt.Length + IV.Length, Закодировано, 0, Закодировано.Длина); byte[] Key = CreateKey(пароль, Salt); используя (Aes aesAlg = Aes.Create()) { aesAlg.Key = Ключ; aesAlg.IV = IV; aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; Декриптор ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); используя (var msDecrypt = новый MemoryStream(Encoded)) { используя (var csDecrypt = новый CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { используя (var srDecrypt = новый StreamReader(csDecrypt)) { открытый текст = srDecrypt.ReadToEnd(); } } } } вернуть открытый текст; } поймать (Исключение e) { вернуть ноль; } } public static byte[] CreateKey(строковый пароль, соль byte[]) { используя (var rfc2898DeriveBytes = новый Rfc2898DeriveBytes (пароль, соль, итерации)) return rfc2898DeriveBytes.GetBytes(32); } частный статический байт[] GetSalt() { вар соль = новый байт[32]; используя (var случайный = новый RNGCryptoServiceProvider()) { Случайный.GetNonZeroBytes(соль); } возвратная соль; } Для решения Javascript я использую CryptoJS, основываясь на этой ссылке http://www.adonespitogo.com/articles/en ... ptojs-aes/
var keySize = 256; вар ivSize = 128; вар saltSize = 256; вар итераций = 1000; var message = «Привет, мир»; var пароль = «Секретный пароль»; функция шифрования (сообщение, проход) { вар соль = CryptoJS.lib.WordArray.random(saltSize/8); ключ var = CryptoJS.PBKDF2(pass, salt, { размер ключа: размер ключа/32, итерации: итерации }); вар iv = CryptoJS.lib.WordArray.random(ivSize/8); var зашифрован = CryptoJS.AES.encrypt(msg, key, { iv: iv, дополнение: CryptoJS.pad.Pkcs7, режим: CryptoJS.mode.CBC }); // соль, длина iv будет 32 в шестнадцатеричном формате // добавляем их в зашифрованный текст для использования при расшифровке вар транзитное сообщение = соль + iv + зашифровано; вернуть транзитное сообщение.toString(); } функция расшифровки (transitmessage, pass) { var salt = CryptoJS.enc.Hex.parse(transitmessage.substr(0, 64)); var iv = CryptoJS.enc.Hex.parse(transitmessage.substr(64, 32)); var зашифровано =transitmessage.substring(96); ключ var = CryptoJS.PBKDF2(pass, salt, { размер ключа: размер ключа/32, итерации: итерации }); var decrypted = CryptoJS.AES.decrypt(зашифровано, ключ, { iv: iv, дополнение: CryptoJS.pad.Pkcs7, режим: CryptoJS.mode.CBC }) return decrypted.toString(CryptoJS.enc.Utf8); } Используемый пароль: Секретный пароль
Результат C#: r7Oi1vMXZ5mYJay8i+slbJZEiT3CxV/1zOYntbZIsS5RuasABJKQQQVvAe50U1deIIqyQiwzQWYelMJ48WWpMQ==
Результат Javascript: 72ff8e7b653efbe3101d2c4ca7d7fe1af06652b907a90281aafa5ae09b45c9af091571b08d3d39cbad129939488319b2pprMQFFEJZR5JlrDsMqT8w==< /п> Результатом должно быть Hello World
Оба решения хорошо работают в своей среде, однако хеши C# или Javascript не подлежат обмену и не расшифровываются. Я предполагаю, что с этим как-то связана кодировка символов, поэтому размеры base64 так сильно различаются. Есть ли у кого-нибудь идея, как заставить это работать вместе? Спасибо!
Я пытаюсь написать два класса на C# и Javascript, которые я могу использовать в своем проекте для шифрования или дешифрования данных с использованием AES при обмене данными.
Используя AES, я встраиваю Salt (32 байта) и IV (16 байт) в зашифрованный результат, при тестировании это отлично работает для обоих классов по отдельности. Добавление Salt и IV в этот микс не приведет к появлению большого количества ссылок на то, чтобы это работало между двумя платформами.
Для C# я использую стандартный System.Security.Crypthography.AES
Private static readonly int iterations = 1000; публичная статическая строка Encrypt (строковый ввод, строковый пароль) { байт[] зашифрован; байт[] IV; байт[] Соль = GetSalt(); byte[] Key = CreateKey(пароль, Salt); используя (Aes aesAlg = Aes.Create()) { aesAlg.Key = Ключ; aesAlg.Padding = PaddingMode.PKCS7; aesAlg.Mode = CipherMode.CBC; aesAlg.GenerateIV(); IV = aesAlg.IV; var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); используя (var msEncrypt = новый MemoryStream()) { используя (var csEncrypt = новый CryptoStream(msEncrypt, шифратор, CryptoStreamMode.Write)) { используя (var swEncrypt = новый StreamWriter(csEncrypt)) { swEncrypt.Write(вход); } зашифровано = msEncrypt.ToArray(); } } } байт[]комбинированныйIvSaltCt = новый байт[Salt.Length + IV.Length + зашифрованный.Length]; Array.Copy(Salt, 0, CombinedIvSaltCt, 0, Salt.Length); Array.Copy(IV, 0,комбинированныйIvSaltCt, Salt.Length, IV.Length); Array.Copy(зашифровано, 0, комбинированноеIvSaltCt, Salt.Length + IV.Length, зашифровано.Length); return Convert.ToBase64String(combinedIvSaltCt.ToArray()); } общедоступная статическая строка Расшифровать (строковый ввод, строковый пароль) { байт [] inputAsByteArray; строка открытого текста = ноль; пытаться { inputAsByteArray = Convert.FromBase64String(вход); байт[] Соль = новый байт[32]; байт[] IV = новый байт[16]; байт[] Закодированный = новый байт[inputAsByteArray.Length - Salt.Length - IV.Length]; Array.Copy(inputAsByteArray, 0, Salt, 0, Salt.Length); Array.Copy(inputAsByteArray, Salt.Length, IV, 0, IV.Length); Array.Copy(inputAsByteArray, Salt.Length + IV.Length, Закодировано, 0, Закодировано.Длина); byte[] Key = CreateKey(пароль, Salt); используя (Aes aesAlg = Aes.Create()) { aesAlg.Key = Ключ; aesAlg.IV = IV; aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; Декриптор ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); используя (var msDecrypt = новый MemoryStream(Encoded)) { используя (var csDecrypt = новый CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { используя (var srDecrypt = новый StreamReader(csDecrypt)) { открытый текст = srDecrypt.ReadToEnd(); } } } } вернуть открытый текст; } поймать (Исключение e) { вернуть ноль; } } public static byte[] CreateKey(строковый пароль, соль byte[]) { используя (var rfc2898DeriveBytes = новый Rfc2898DeriveBytes (пароль, соль, итерации)) return rfc2898DeriveBytes.GetBytes(32); } частный статический байт[] GetSalt() { вар соль = новый байт[32]; используя (var случайный = новый RNGCryptoServiceProvider()) { Случайный.GetNonZeroBytes(соль); } возвратная соль; } Для решения Javascript я использую CryptoJS, основываясь на этой ссылке http://www.adonespitogo.com/articles/en ... ptojs-aes/
var keySize = 256; вар ivSize = 128; вар saltSize = 256; вар итераций = 1000; var message = «Привет, мир»; var пароль = «Секретный пароль»; функция шифрования (сообщение, проход) { вар соль = CryptoJS.lib.WordArray.random(saltSize/8); ключ var = CryptoJS.PBKDF2(pass, salt, { размер ключа: размер ключа/32, итерации: итерации }); вар iv = CryptoJS.lib.WordArray.random(ivSize/8); var зашифрован = CryptoJS.AES.encrypt(msg, key, { iv: iv, дополнение: CryptoJS.pad.Pkcs7, режим: CryptoJS.mode.CBC }); // соль, длина iv будет 32 в шестнадцатеричном формате // добавляем их в зашифрованный текст для использования при расшифровке вар транзитное сообщение = соль + iv + зашифровано; вернуть транзитное сообщение.toString(); } функция расшифровки (transitmessage, pass) { var salt = CryptoJS.enc.Hex.parse(transitmessage.substr(0, 64)); var iv = CryptoJS.enc.Hex.parse(transitmessage.substr(64, 32)); var зашифровано =transitmessage.substring(96); ключ var = CryptoJS.PBKDF2(pass, salt, { размер ключа: размер ключа/32, итерации: итерации }); var decrypted = CryptoJS.AES.decrypt(зашифровано, ключ, { iv: iv, дополнение: CryptoJS.pad.Pkcs7, режим: CryptoJS.mode.CBC }) return decrypted.toString(CryptoJS.enc.Utf8); } Используемый пароль: Секретный пароль
Результат C#: r7Oi1vMXZ5mYJay8i+slbJZEiT3CxV/1zOYntbZIsS5RuasABJKQQQVvAe50U1deIIqyQiwzQWYelMJ48WWpMQ==
Результат Javascript: 72ff8e7b653efbe3101d2c4ca7d7fe1af06652b907a90281aafa5ae09b45c9af091571b08d3d39cbad129939488319b2pprMQFFEJZR5JlrDsMqT8w==< /п> Результатом должно быть Hello World
Оба решения хорошо работают в своей среде, однако хеши C# или Javascript не подлежат обмену и не расшифровываются. Я предполагаю, что с этим как-то связана кодировка символов, поэтому размеры base64 так сильно различаются. Есть ли у кого-нибудь идея, как заставить это работать вместе? Спасибо!
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как доказать 128-битное шифрование и дешифрование AES на Arduino [закрыто]
Anonymous » » в форуме C++ - 0 Ответы
- 55 Просмотры
-
Последнее сообщение Anonymous
-