2010-01-29 147 views
1

C#如何做到这一点:J2ME加密C#解密和J2ME解密C#加密?

string    keystr   = "abcdefabcdef"; 
string    plainText = "www.bouncycastle.org"; 
    RijndaelManaged crypto = new RijndaelManaged(); 

    crypto.KeySize = 128; 
    crypto.Mode = CipherMode.CBC; 
    crypto.Padding = PaddingMode.PKCS7; 
    crypto.Key = keystr.ToCharArray().Select(c=>(byte)c).ToArray(); 
    // get the IV and key for writing to a file 
    byte[] iv = crypto.IV; 
    byte[] key = crypto.Key; 


    // turn the message into bytes 
    // use UTF8 encoding to ensure that Java can read in the file properly 
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText.ToCharArray()); 

    // Encrypt the Text Message using AES (Rijndael) (Symmetric algorithm) 
    ICryptoTransform sse = crypto.CreateEncryptor(); 
    MemoryStream encryptedFs = new MemoryStream(); 
    CryptoStream cs = new CryptoStream(encryptedFs, sse, CryptoStreamMode.Write); 
    try 
    { 
    cs.Write(plainBytes, 0, plainBytes.Length); 
    cs.FlushFinalBlock(); 
    encryptedFs.Position = 0; 

    string result = string.Empty; 
    for (int i = 0; i < encryptedFs.Length; i++) 
    { 
     int read = encryptedFs.ReadByte(); 
     result += read.ToString("x2"); 
    } 

    } 
    catch (Exception e) 
    { 
    Console.WriteLine(e.Message); 

    } 
    finally 
    { 
    encryptedFs.Close(); 
    cs.Close(); 

    } 
} 

的Java:

private String    key   = "abcdefabcdef"; 
private String    plainText = "www.bouncycastle.org"; 

cipherText = performEncrypt(Hex.decode(key.getBytes()), plainText); 

private byte[] performEncrypt(byte[] key, String plainText) 
{ 
    byte[] ptBytes = plainText.getBytes(); 
    final RijndaelEngine rijndaelEngine = new RijndaelEngine(); 


    cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(rijndaelEngine)); 

    String name = cipher.getUnderlyingCipher().getAlgorithmName(); 
    message("Using " + name); 
    byte[]iv = new byte[16]; 
    final KeyParameter keyParameter = new KeyParameter(key); 

    cipher.init(true, keyParameter); 



    byte[] rv = new byte[cipher.getOutputSize(ptBytes.length)]; 

    int oLen = cipher.processBytes(ptBytes, 0, ptBytes.length, rv, 0); 
    try 
    { 
     cipher.doFinal(rv, oLen); 
    } 
    catch (CryptoException ce) 
    { 
     message("Ooops, encrypt exception"); 
     status(ce.toString()); 
    } 
    return rv; 
} 

C#生产:ff53bc51c0caf5de53ba850f7ba08b58345a89a51356d0e030ce1367606c5f08
java的产生:375c52fd202696dba679e57f612ee95e707ccb05aff368b62b2802d5fb685403

有人可以帮我解决我的代码?

回答

0

我认为这个算法的构建方式略有不同,或者盐键以不同的方式插入。

1

在Java代码中,您不使用IV。

我不够精通C#来直接帮助你,但我可以提供一些信息。

Rijndael,又名“AES”,加密16个字节的块。要加密长消息(例如,当您的测试消息,编码时,长度为20个字节),必须多次调用Rijndael,以某种方式将调用链接在一起(还有一些“填充”以确保输入长度是16的倍数)。 CBC模式执行这种链接。

在CBC中,每个数据块在自身加密之前与前一个加密块组合(按位异或)。由于第一块数据没有先前的块,我们添加一个新的常规“零块”,称为IV。 IV应该被选为16个随机字节。解密方将需要IV。 IV不需要保密(这是IV和密钥之间的区别),所以它通常沿着消息传输。

在您的Java代码中,您没有指定IV,只需创建一个名为iv的变量并且不要使用它。所以Rijndael的实现是独立的。有可能它会产生一个随机的IV。同样,你也不会给C#代码中的Rijndael实现IV。因此,再次选择随机IV是非常合理的。但与Java代码中的不一样,因此具有不同的结果。 (注意:你将20字节的输入字符串填充到32个字节,你给出了两个十六进制的“结果”,每个长度为32字节,这是一致的,但意味着这些结果不包括IV - 否则它们将是48字节长。)