让SlowAES和RijndaelManaged类在.NET中一起玩
我正在尝试使用javascript库和.NET中的类设置AES加密/解密 我在阅读后选择了这种方法,Cheeso设法将这两种加密方法结合在一起 “在我的测试中 COM包装的SlowAEs,我使用CBC模式, 加密是完全正确的 与RijndaelManager兼容 NET中的类“-Cheeso 我从Cheeso的Windows脚本组件(最新的slowaes库)中获取了javascript代码,并使用以下javascript脚本进行测试:让SlowAES和RijndaelManaged类在.NET中一起玩,.net,javascript,aes,rijndaelmanaged,pbkdf2,.net,Javascript,Aes,Rijndaelmanaged,Pbkdf2,我正在尝试使用javascript库和.NET中的类设置AES加密/解密 我在阅读后选择了这种方法,Cheeso设法将这两种加密方法结合在一起 “在我的测试中 COM包装的SlowAEs,我使用CBC模式, 加密是完全正确的 与RijndaelManager兼容 NET中的类“-Cheeso 我从Cheeso的Windows脚本组件(最新的slowaes库)中获取了javascript代码,并使用以下javascript脚本进行测试: var key = "1234567890123456789
var key = "12345678901234567890123456789012";
var message = "watson?";
var decrypted;
slowAES.aes.keySize.SIZE_256;
slowAES.modeOfOperation.CBC;
put_PassPhrase(key);
var result = EncryptString(message);
decrypted = DecryptCommaDelimitedStringToString(result)
document.write("Key:" + key + "<br />original:" + message + "<br />Cypher:" + result + "<br />Decrypted:" + decrypted + "<br />IV(): " + get_IV());
我修改了以下示例,以尝试匹配C#中的加密:
监视字节数组:
- encrypted {byte[16]} byte[]
[0] 139 byte
[1] 104 byte
[2] 166 byte
[3] 35 byte
[4] 8 byte
[5] 42 byte
[6] 216 byte
[7] 160 byte
[8] 235 byte
[9] 153 byte
[10] 23 byte
[11] 143 byte
[12] 105 byte
[13] 3 byte
[14] 24 byte
[15] 255 byte
我已经尝试了托管.NET类的所有填充选项,但是我无法获得匹配的加密输出。有人能帮我吗
谢谢
鲍勃也许我能帮上忙
我把你的C#代码稍微修改了一下。我使用的C#代码整体上是:
using System;
using System.Security.Cryptography;
public class Bob
{
internal static string FormatByteArray(byte[] b)
{
System.Text.StringBuilder sb1 = new System.Text.StringBuilder();
int i = 0;
for (i = 0; i < b.Length; i++)
{
if (i != 0 && i % 16 == 0)
sb1.Append("\n");
sb1.Append(System.String.Format("{0:X2} ", b[i]));
}
return sb1.ToString();
}
public static void Main()
{
try
{
string original = "watson?";
Console.WriteLine("Original: {0}", original);
byte[] IV = new byte[16]; // match slowaes IV
var ascii = new System.Text.ASCIIEncoding();
// match slowaes KEY
string passPhrase = "12345678901234567890123456789012";
byte[] key = ascii.GetBytes(passPhrase);
RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.BlockSize = 128;
myRijndael.KeySize = 256;
myRijndael.IV = IV;
myRijndael.Padding = PaddingMode.PKCS7;
myRijndael.Mode = CipherMode.CBC;
myRijndael.Key = key;
// Encrypt the string to an array of bytes.
byte[] plainText = new System.Text.ASCIIEncoding().GetBytes(original);
ICryptoTransform transform = myRijndael.CreateEncryptor();
byte[] cipherText = transform.TransformFinalBlock(plainText, 0, plainText.Length);
Console.WriteLine("cipherText: {0}", FormatByteArray(cipherText));
// Decrypt the bytes to a string.
transform = myRijndael.CreateDecryptor();
plainText = transform.TransformFinalBlock(cipherText, 0, cipherText.Length);
string roundtrip = ascii.GetString(plainText);
Console.WriteLine("Round Trip: {0}", roundtrip);
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}
}
}
我使用了您引用的另一篇文章中的slowAES.wsc,但有两个更改:我不为EncryptString或DecryptString()方法中的密钥调用getPaddedBlock()。这确实需要一个PBKDF,但现在我们不必担心。以下是修改后的EncryptString的外观:
function EncryptString(plainText)
{
// this is really wrong - need a PBBKDF to get the key, instead
// of just using the passphrase
var key = cryptoHelpers.convertStringToByteArray(_passphrase);
// var nkey = slowAES.getPaddedBlock(key, 0, _keysize, _mode);
var bytesToEncrypt = cryptoHelpers.convertStringToByteArray(plainText);
var result = slowAES.encrypt(bytesToEncrypt,
_mode,
key,
_keysize,
_iv);
return result['cipher'];
}
这意味着您必须使用与密钥大小要求的长度完全相同的密码短语。如果使用AES256,则传递一个32字符字符串(32*8=256位)。看来你已经明白了
WSC组件的客户端也是Javascript(尽管它可以是任何COM语言)。这是我用过的
function toHexString(a)
{
var ret = '';
for(var i = 0;i < a.length;i++)
ret += (a[i] < 16 ? '0' : '') + a[i].toString(16) + ' ';
return ret.toLowerCase();
}
//var plaintext = "Hello. This is a test. of the emergency broadcasting system.";
var plaintext = "watson?";
try
{
WScript.echo( "plaintext: " + plaintext);
WScript.echo( "plaintext.length: " + plaintext.length);
WScript.echo( "instantiate ");
var aes = new ActiveXObject("Ionic.Com.SlowAES");
WScript.echo( "keysize ");
aes.KeySize = 256;
WScript.echo( "passphrase ");
aes.PassPhrase= "12345678901234567890123456789012"; // 32 chars long
WScript.echo( "mode ");
aes.Mode = "CBC";
WScript.echo( "encrypting... ");
var result = aes.EncryptString(plaintext);
WScript.echo( "Cryptotext: " + toHexString(result));
WScript.echo( "decrypting... ");
var decrypted = aes.DecryptBytesToString(result);
WScript.echo( "decrypted: " + decrypted);
}
catch(e)
{
WScript.echo("Exception: " + e);
// WScript.echo(e.Number + ": " + e.Name);
WScript.echo(e.Message);
}
它在这两种情况下都成功解密
编辑:虽然我将slowAES加密打包在WSC中,但它也可以在COM环境之外运行。WSC部分对于这个问题是不必要的,但对于证明之前问题的答案是必要的,该问题的答案是“”
EDIT2:演示Javascript或VBScript与.NET之间AES互操作的源代码。我扩展了这里给出的基本示例,以生成3种语言的测试应用程序:C#、Javascript和VBScript。它们都采用相同的参数集。它们各自使用符合RFC2898的密钥派生函数。您可以指定密码、salt、IV和明文,以及要在PBKDF2中使用的RFC2898迭代次数。您可以轻松地验证每个测试程序的密文是否相同。也许这个例子对某些人有用
EDIT3一本好书:我真的很尊重你为帮助别人所付出的努力+1.@奇索:我真的很佩服你解决这个问题的工作。干得好。@DanielLittle-很抱歉耽搁了。该链接现在处于活动状态。
csc.exe /target:exe /out:Bob.exe Bob.cs
function EncryptString(plainText)
{
// this is really wrong - need a PBBKDF to get the key, instead
// of just using the passphrase
var key = cryptoHelpers.convertStringToByteArray(_passphrase);
// var nkey = slowAES.getPaddedBlock(key, 0, _keysize, _mode);
var bytesToEncrypt = cryptoHelpers.convertStringToByteArray(plainText);
var result = slowAES.encrypt(bytesToEncrypt,
_mode,
key,
_keysize,
_iv);
return result['cipher'];
}
function toHexString(a)
{
var ret = '';
for(var i = 0;i < a.length;i++)
ret += (a[i] < 16 ? '0' : '') + a[i].toString(16) + ' ';
return ret.toLowerCase();
}
//var plaintext = "Hello. This is a test. of the emergency broadcasting system.";
var plaintext = "watson?";
try
{
WScript.echo( "plaintext: " + plaintext);
WScript.echo( "plaintext.length: " + plaintext.length);
WScript.echo( "instantiate ");
var aes = new ActiveXObject("Ionic.Com.SlowAES");
WScript.echo( "keysize ");
aes.KeySize = 256;
WScript.echo( "passphrase ");
aes.PassPhrase= "12345678901234567890123456789012"; // 32 chars long
WScript.echo( "mode ");
aes.Mode = "CBC";
WScript.echo( "encrypting... ");
var result = aes.EncryptString(plaintext);
WScript.echo( "Cryptotext: " + toHexString(result));
WScript.echo( "decrypting... ");
var decrypted = aes.DecryptBytesToString(result);
WScript.echo( "decrypted: " + decrypted);
}
catch(e)
{
WScript.echo("Exception: " + e);
// WScript.echo(e.Number + ": " + e.Name);
WScript.echo(e.Message);
}
8B 68 A6 23 08 2A D8 A0 EB 99 17 8F 69 03 18 FF