CryptoJS Расшифровка C# DES Ошибка зашифрованного файла
У нас есть XML-файл, который отслеживает прогресс пользователей на уроках в отдельном учебном приложении. XML зашифрован DES -> преобразован в строку base64 -> записан в файл с помощью следующего кода C#
protected static byte[] key = new byte[] { 0x8c, 0x04, 0xD1, 0x1E, 0x14, 0xE2, 0x51, 0xDD };
protected static byte[] iv = new byte[] { 0x96, 0xCF, 0x3A, 0x0D, 0x7D, 0x80, 0xDA, 0xA8 };
protected static int DefBlockSize = 64;
public static string Encrypt(string originalString)
{
if (String.IsNullOrEmpty(originalString))
{
throw new ArgumentNullException("Cannot decrypt a null input string");
}
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
cryptoProvider.BlockSize = DefBlockSize;
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateEncryptor(key, iv), CryptoStreamMode.Write);
StreamWriter writer = new StreamWriter(cryptoStream);
writer.Write(originalString);
writer.Flush();
cryptoStream.FlushFinalBlock();
writer.Flush();
return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int) memoryStream.Length);
}
public static void EncryptToFile(string originalString, string filePath)
{
string base64String = DESEncryption.Encrypt(originalString);
File.WriteAllBytes(filePath, Convert.FromBase64String(base64String));
}
Расшифровка прекрасно работает в автономном приложении со следующим кодом:
protected override StreamReader LoadAsTextFile (string fileSystemPath)
{
String base64EncryptedString = Convert.ToBase64String(File.ReadAllBytes(fileSystemPath));
CryptoStream cs = DESEncryption.DecryptToCryptoStream(base64EncryptedString);
StreamReader sr = new StreamReader(cs, true);
return sr;
}
public static CryptoStream DecryptToCryptoStream(string base64EncryptedString)
{
if (string.IsNullOrEmpty(base64EncryptedString))
{
throw new ArgumentNullException("Cannot decrypt a null input string");
}
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
cryptoProvider.BlockSize = DefBlockSize;
MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(base64EncryptedString));
CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateDecryptor(key, iv), CryptoStreamMode.Read);
return cryptoStream;
}
В качестве более простого теста я DES зашифровал строку DateTime "02.10.2014 10:54:25 AM" в этом формате. Это строка base64 после шифрования: P3Zj7NFQ8nUdM3FchVMxWEERB0oyOr4z. Если я вручную установлю эту строку base64 в js/cryptojs (см. Ниже), я смогу успешно расшифровать изначально (C#) зашифрованную дату и время в js/cryptojs.
var base64 = "P3Zj7NFQ8nUdM3FchVMxWEERB0oyOr4z";
var utf8 = base64.toString(CryptoJS.enc.Utf8);
var decrypted = CryptoJS.DES.decrypt(utf8, key, { iv: iv });
var decText = decrypted.toString(CryptoJS.enc.Utf8);
// decrypts correctly to 10/2/2014 10:54:25 AM
Я просто не могу загрузить данные обратно из сохраненного файла, используя readAsArrayBuffer или readAsBinaryString. Если я использую readAsBinaryString с js ниже, строка base64, которую я получаю после прочтения файла-> преобразования в base64, немного отличается от значения, которое я вижу в C# до сохранения файла. ("P3Zjw6zDkVDDsnUdM3FcwoVTMVhBEQdKMjrCvjM =" в javascript и "P3Zj7NFQ8nUdM3FchVMxWEERB0oyOr4z" в C# перед записью в файл).
if (window.File && window.FileReader && window.FileList && window.Blob)
{
var r = new FileReader();
var parser = new DOMParser();
r.onload = function(e)
{
var key = CryptoJS.enc.Hex.parse('8c04D11E14E251DD');
var iv = CryptoJS.enc.Hex.parse('96CF3A0D7D80DAA8');
var data = e.target.result;
var parsedWordArray = CryptoJS.enc.Utf8.parse(data);
var base64string = CryptoJS.enc.Base64.stringify(parsedWordArray);
var utf8 = base64string.toString(CryptoJS.enc.Utf8);
var decrypted = CryptoJS.DES.decrypt(utf8, key, { iv: iv });
var decText = decrypted.toString(CryptoJS.enc.Utf8);
alert("Made it past decryption");
}
//r.readAsArrayBuffer(gXMLFile);
r.readAsBinaryString(gXMLFile);
}
1 ответ
У меня та же проблема здесь. Мой пароль хранится в Unity, но я должен прочитать их с помощью JS. Благодаря вашему посту, это меня вдохновило. И я наконец-то вышел с некоторым результатом.
Вы уверены, что "02.10.2014 10:54:25 AM" после Base64 будет "P3Zj7NFQ8nUdM3FchVMxWEERB0oyOr4z"? Я думаю, что это твоя проблема.
Кстати, я использую эту функцию, она отлично работает:
CryptoJS.decodePasswardForUnity = function (encryted, key = '71617A7365646366', iv = "1234567890abcdef") {
let C = CryptoJS;
encrytedBase64 = C.enc.Base64.parse(encryted);
toDecrypt = C.enc.Hex.parse(encrytedBase64.toString());
let res = C.DES.decrypt(C.lib.CipherParams.create({ ciphertext: toDecrypt }), C.enc.Hex.parse(key), { iv: C.enc.Hex.parse(iv), mode: C.mode.CBC});
return C.enc.Utf8.stringify(C.enc.Hex.parse(res.toString()));
};
CryptoJS.encodePasswardAsUnity = function (password, key = '71617A7365646366', iv = "1234567890abcdef") {
let C = CryptoJS;
toEncode = C.enc.Hex.parse(C.enc.Utf8.parse(password).toString());
let res = C.DES.encrypt(toEncode, C.enc.Hex.parse(key), { iv: C.enc.Hex.parse(iv), mode: C.mode.CBC}).ciphertext;
return C.enc.Base64.stringify(res);
};
надеюсь, это поможет вам