使用 vb.net AES/CBC 加密字符串,需要使用 JavaScript CryptoJS 解密
Encrypt string using vb.net AES/CBC and need to decrypt using JavaScript CryptoJS
我有一个 vb.net Windows 表单应用程序,可以将字符串加密到文件中。我现在需要 JavaScript 来解密该值。我曾尝试使用 CryptoJS,但我在语法以及如何以正确的格式获取密码、salt 和 init 向量以在 CryptoJS.PBKDF2 中使用(假设这是正确的使用)。
调用方法
Dim encryptedComplianceValue = encrypt2(complianceValue, "Password", "Salt Value", "SHA1", 2, "@1B2c3D4e5F6g7H8", 256)
加密方式
Public Function encrypt2(ByVal plainText As String, ByVal passPhrase As String, ByVal saltValue As String, ByVal hashAlgorithm As String, ByVal passwordIterations As Integer, ByVal initVector As String, ByVal keySize As Integer) As String
Dim initVectorBytes As Byte()
initVectorBytes = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte()
saltValueBytes = Encoding.ASCII.GetBytes(saltValue)
Dim plainTextBytes As Byte()
plainTextBytes = Encoding.UTF8.GetBytes(plainText)
Dim password As Rfc2898DeriveBytes
password = New Rfc2898DeriveBytes(passPhrase, saltValueBytes, passwordIterations)
Dim keyBytes As Byte()
keyBytes = password.GetBytes(keySize / 8)
Dim symmetricKey As RijndaelManaged
symmetricKey = New RijndaelManaged()
symmetricKey.Mode = CipherMode.CBC
Dim encryptor As ICryptoTransform
encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)
Dim memoryStream As MemoryStream
memoryStream = New MemoryStream()
Dim cryptoStream As CryptoStream
cryptoStream = New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
cryptoStream.FlushFinalBlock()
Dim cipherTextBytes As Byte()
cipherTextBytes = memoryStream.ToArray()
memoryStream.Close()
cryptoStream.Close()
Dim cipherText As String
cipherText = Convert.ToBase64String(cipherTextBytes)
Return cipherText
End Function
JavaScript
function decryptMsg256()
{
var keySize = 256;
var iterations = 2;
var algorithm = 'AES-256-CBC';
// the password that user provides
var userPass = "Password";
console.log("user pass : " + userPass);
// get the encrypted msg
var encMsg64 = "v6shkblimfQMOoa8VxICjQ==";
var encMsg = CryptoJS.enc.Base64.parse(encMsg64);
//var salt =CryptoJS.enc.Utf8.parse("Mon,07-Mar-2016 18:50:46 GMT");
var salt = "Salt Value";
console.log('salt: '+ salt);
var saltbytes = [];
for (var i = 0; i <salt.length; ++i) {
saltbytes .push(salt.charCodeAt(i));
}
console.log('saltbytes: '+ saltbytes );
//var iv =CryptoJS.enc.Utf8.parse("@1B2c3D4e5F6g7H8");
var iv = "@1B2c3D4e5F6g7H8";
console.log('IV: '+ iv);
var ivbytes = [];
for (var i = 0; i <iv.length; ++i) {
ivbytes.push(iv.charCodeAt(i));
}
console.log('ivbytes: '+ ivbytes );
//var saltBuffer = new Buffer(salt);
//var passwordBuffer = new Buffer(userPass);
var key = CryptoJS.PBKDF2(userPass, saltbytes,{keyBytes: 32, iterations: 2 });
//var key = CryptoJS.PBKDF2(userPass, salt, iterations, keySize/8);
//var decipher = CryptoJS.createDecipheriv(algorithm, key, iv);
console.log( 'key: '+ key);
var keybytes = [];
for (var i = 0; i <key.length; ++i) {
keybytes.push(key.charCodeAt(i));
}
console.log('keybytes: '+ keybytes);
//var plainText="Hello, World!";
//console.log('Plain Text '+ plainText );
//var encMsg = CryptoJS.AES.encrypt(plainText, key, {
// iv:iv,
// mode: CryptoJS.mode.CBC,
// padding: CryptoJS.pad.Pkcs7
// });
//console.log('Encrypted Message '+ encMsg );
var decText = '';
var decMsg = CryptoJS.AES.decrypt( encMsg, key, {
iv:iv,
mode: CryptoJS.mode.CBC,
//padding: CryptoJS.pad.Pkcs7
} );
//console.log( "decryptedData = " + decMsg );
// convert to UTF8 string
decText = decMsg.toString( CryptoJS.enc.Utf8);
console.log( "decryptedText = " + decText );
}
您有多个问题:
您的 IV 是一个简单的 ASCII 字符串,因此您可以使用
轻松地将其解析为二进制格式
var iv = CryptoJS.enc.Utf8.parse("@1B2c3D4e5F6g7H8");
不要将您的自定义 "binary" 格式与 saltbytes.push(salt.charCodeAt(i));
或类似格式一起使用。您需要使用 CryptoJS 的原生格式,可通过
CryptoJS.enc.<Encoder>.parse(string)
PBKDF2 的输出大小用 keySize
指定,而不是 keyBytes
:
var key = CryptoJS.PBKDF2(userPass, salt, {keySize: 256/32, iterations: 2 });
解密函数期望密文是一个CipherParams对象。好东西,鸭子打字有效:
var decMsg = CryptoJS.AES.decrypt({
ciphertext: encMsg
}, key, {
iv: iv
});
我有一个 vb.net Windows 表单应用程序,可以将字符串加密到文件中。我现在需要 JavaScript 来解密该值。我曾尝试使用 CryptoJS,但我在语法以及如何以正确的格式获取密码、salt 和 init 向量以在 CryptoJS.PBKDF2 中使用(假设这是正确的使用)。
调用方法
Dim encryptedComplianceValue = encrypt2(complianceValue, "Password", "Salt Value", "SHA1", 2, "@1B2c3D4e5F6g7H8", 256)
加密方式
Public Function encrypt2(ByVal plainText As String, ByVal passPhrase As String, ByVal saltValue As String, ByVal hashAlgorithm As String, ByVal passwordIterations As Integer, ByVal initVector As String, ByVal keySize As Integer) As String
Dim initVectorBytes As Byte()
initVectorBytes = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte()
saltValueBytes = Encoding.ASCII.GetBytes(saltValue)
Dim plainTextBytes As Byte()
plainTextBytes = Encoding.UTF8.GetBytes(plainText)
Dim password As Rfc2898DeriveBytes
password = New Rfc2898DeriveBytes(passPhrase, saltValueBytes, passwordIterations)
Dim keyBytes As Byte()
keyBytes = password.GetBytes(keySize / 8)
Dim symmetricKey As RijndaelManaged
symmetricKey = New RijndaelManaged()
symmetricKey.Mode = CipherMode.CBC
Dim encryptor As ICryptoTransform
encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)
Dim memoryStream As MemoryStream
memoryStream = New MemoryStream()
Dim cryptoStream As CryptoStream
cryptoStream = New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
cryptoStream.FlushFinalBlock()
Dim cipherTextBytes As Byte()
cipherTextBytes = memoryStream.ToArray()
memoryStream.Close()
cryptoStream.Close()
Dim cipherText As String
cipherText = Convert.ToBase64String(cipherTextBytes)
Return cipherText
End Function
JavaScript
function decryptMsg256()
{
var keySize = 256;
var iterations = 2;
var algorithm = 'AES-256-CBC';
// the password that user provides
var userPass = "Password";
console.log("user pass : " + userPass);
// get the encrypted msg
var encMsg64 = "v6shkblimfQMOoa8VxICjQ==";
var encMsg = CryptoJS.enc.Base64.parse(encMsg64);
//var salt =CryptoJS.enc.Utf8.parse("Mon,07-Mar-2016 18:50:46 GMT");
var salt = "Salt Value";
console.log('salt: '+ salt);
var saltbytes = [];
for (var i = 0; i <salt.length; ++i) {
saltbytes .push(salt.charCodeAt(i));
}
console.log('saltbytes: '+ saltbytes );
//var iv =CryptoJS.enc.Utf8.parse("@1B2c3D4e5F6g7H8");
var iv = "@1B2c3D4e5F6g7H8";
console.log('IV: '+ iv);
var ivbytes = [];
for (var i = 0; i <iv.length; ++i) {
ivbytes.push(iv.charCodeAt(i));
}
console.log('ivbytes: '+ ivbytes );
//var saltBuffer = new Buffer(salt);
//var passwordBuffer = new Buffer(userPass);
var key = CryptoJS.PBKDF2(userPass, saltbytes,{keyBytes: 32, iterations: 2 });
//var key = CryptoJS.PBKDF2(userPass, salt, iterations, keySize/8);
//var decipher = CryptoJS.createDecipheriv(algorithm, key, iv);
console.log( 'key: '+ key);
var keybytes = [];
for (var i = 0; i <key.length; ++i) {
keybytes.push(key.charCodeAt(i));
}
console.log('keybytes: '+ keybytes);
//var plainText="Hello, World!";
//console.log('Plain Text '+ plainText );
//var encMsg = CryptoJS.AES.encrypt(plainText, key, {
// iv:iv,
// mode: CryptoJS.mode.CBC,
// padding: CryptoJS.pad.Pkcs7
// });
//console.log('Encrypted Message '+ encMsg );
var decText = '';
var decMsg = CryptoJS.AES.decrypt( encMsg, key, {
iv:iv,
mode: CryptoJS.mode.CBC,
//padding: CryptoJS.pad.Pkcs7
} );
//console.log( "decryptedData = " + decMsg );
// convert to UTF8 string
decText = decMsg.toString( CryptoJS.enc.Utf8);
console.log( "decryptedText = " + decText );
}
您有多个问题:
您的 IV 是一个简单的 ASCII 字符串,因此您可以使用
轻松地将其解析为二进制格式var iv = CryptoJS.enc.Utf8.parse("@1B2c3D4e5F6g7H8");
不要将您的自定义 "binary" 格式与
saltbytes.push(salt.charCodeAt(i));
或类似格式一起使用。您需要使用 CryptoJS 的原生格式,可通过CryptoJS.enc.<Encoder>.parse(string)
PBKDF2 的输出大小用
keySize
指定,而不是keyBytes
:var key = CryptoJS.PBKDF2(userPass, salt, {keySize: 256/32, iterations: 2 });
解密函数期望密文是一个CipherParams对象。好东西,鸭子打字有效:
var decMsg = CryptoJS.AES.decrypt({ ciphertext: encMsg }, key, { iv: iv });