获取SlowAES和RijndaelManaged类在.NET一起玩 [英] Getting SlowAES and RijndaelManaged class in .NET to play together

查看:293
本文介绍了获取SlowAES和RijndaelManaged类在.NET一起玩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的JavaScript库 SlowAES 和<一href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx">RijndaelManaged类.NET。

I'm trying to setup AES encryption / decryption using the javascript library SlowAES and the RijndaelManaged class in .NET.

我选择了这个方法后,阅读这个帖子,其中Cheeso已经设法获得这两种加密方式,一起玩

I chose this method after reading this post, where Cheeso has managed to get these two encryption methods to play together

在我的测试中   COM包裹-SlowAEs,我用CBC模式,   和加密完全   与RijndaelManaged的兼容   在.NET级 - Cheeso

"In my tests of the COM-wrapped-SlowAEs, I used CBC mode, and the encryption was completely compatible with the RijndaelManaged class in .NET" - Cheeso

我已经采取了从Cheeso的Windows脚本组件,最新slowaes库的JavaScript code,并使用下面的JavaScript脚本进行测试:

I've taken the javascript code from Cheeso's Windows Scripting Component, the latest slowaes libraries, and using the following javascript script to test:

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());

我收到以下输出:

I'm getting the following output:

Key:12345678901234567890123456789012
original:watson?
Cypher:245,159,1,1,168,1,1,143,1,1,146,1,1,239,117,1
Decrypted:watson? 
IV(): 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

我修改了下面的例子中 MSDN上来尝试并匹配在C#中的加密方式:

I've modified the following example found on MSDN to try and match the encryption in C# :

public static void Main()
        {
            try
            {
                string original = "watson?";
                byte[] IV = new byte[16];   // match slowaes IV
                byte[] key = new System.Text.ASCIIEncoding().GetBytes("12345678901234567890123456789012");// match slowaes KEY

                RijndaelManaged myRijndael = new RijndaelManaged();
                myRijndael.BlockSize = 128;
                myRijndael.KeySize = 256;
                myRijndael.Mode = CipherMode.CBC;

                // Encrypt the string to an array of bytes.
                byte[] encrypted = encryptStringToBytes_AES(original, key, IV);

                // Decrypt the bytes to a string.
                string roundtrip = decryptStringFromBytes_AES(encrypted, key, IV);

                //Display the original data and the decrypted data.
                Console.WriteLine("Original:   {0}", original);
                Console.WriteLine("Round Trip: {0}", roundtrip);

            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.Message);
            }
        }

字节数组的观察:

Watch of the byte array:

-  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类的填充选项,但我不能得到加密的输出相匹配。谁能帮我?

I've tried all the padding options with the managed .NET class, however I can't get the encrypted outputs to match. Can anyone help me?

谢谢

鲍勃·

推荐答案

也许我可以提供帮助。

maybe I can help.

我把你的C#code和修改稍微。在C#code我用的,其全部是:

I took your C# code and modified it slightly. The C# code I use, in its entirety, is:

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);
        }
    }

}

编译上面

csc.exe /target:exe /out:Bob.exe Bob.cs

我用的是slowAES.wsc从您参考,以2改变其他职位:我不叫getPaddedBlock()在EncryptString或DecryptString()方法的关键。这确实需要一个PBKDF但我们不要担心,现在。下面是修改后的EncryptString如下:

I use the slowAES.wsc from the other post you referenced, with 2 changes: I do not call getPaddedBlock() for the key in the EncryptString or DecryptString() methods. This really needs a PBKDF but let's not worry about that now. Here's what the modified EncryptString looks like:

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位)。好像你已经想通了这一点。

This means you have to use a passPhrase that is exactly the length required by the keysize. If you use AES256, then pass a 32-char string (32 * 8 = 256 bits). Seems like you figured this out already.

自来水公司组件的客户机也使用Javascript(尽管它可以是任何COM语言)。下面是我用的东西。

The client of the WSC component is also Javascript (though it can be any COM language). Here's what I used.

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);
}

如果我再运行该code,在Javascript和C#产生相同的密文为明文沃森?,采用AES256,对12345678901234567890123456789012密码,以及16个字节的零IV。生成的密文是:

If I then run this code, the Javascript and C# produces the same cipher text for a plaintext of "watson?", using AES256, passphrase of 12345678901234567890123456789012, and an IV of 16 bytes of zero. The ciphertext generated is:

8B 68 A6 23 08 2A D8 A0 EB 99 17 8F 69 03 18 FF

它成功地解密在这两种情况下。

It successfully decrypts in both cases.

修改:虽然我打包在一个WSC的slowAES加密,这将是COM环境外互操作的运行也是如此。自来水公司的部分是不必要的这个问题,但必要证明了之前的问题,这是的我怎样才能得到VBScript和.NET AES进行互操作?

EDIT: Though I packaged the slowAES encryption in a WSC, it will be interoperable running outside the COM environment as well. The WSC part is unnecessary for this question, but was necessary to demonstrate the answer for a prior question, which was, "how can I get VBScript and .NET AES to interoperate?"

EDIT2 :源$ C ​​$ C,演示了Javascript或VBScript和.NET的可用。我伸出这里给出产生3种语言的测试应用程序的基本例如:C#,JavaScript和VBScript中。他们都采取相同的参数集。他们每个人都使用RFC2898标准的密钥导出函数。可以指定密码,盐,IV和明文,以及RFC2898迭代次数的PBKDF2使用。你可以很容易验证该密文是相同的每个这些测试程序。也许这个例子将是有用的人。

EDIT2: The source code that demonstrates AES interop between Javascript or VBScript and .NET is available. I extended the basic example given here to produce test apps in 3 languages: C#, Javascript and VBScript. They all take the same set of arguments. They each use a RFC2898-compliant key derivation function. You can specify the password, salt, IV, and plaintext, as well as the number of RFC2898 iterations to use in the PBKDF2. You can easily verify that the ciphertext is the same for each of these test programs. Maybe the example will be useful for someone.

EDIT3
一个良好的阅读。 Javascript的密码被认为是有害

EDIT3
a good read: Javascript Cryptography considered harmful.

这篇关于获取SlowAES和RijndaelManaged类在.NET一起玩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆