2010-01-29 17 views
1

C#Comment faire ceci: J2ME crypter C# decrypt Et J2ME décrypter C# encrypt?

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# produit: ff53bc51c0caf5de53ba850f7ba08b58345a89a51356d0e030ce1367606c5f08
java produit: 375c52fd202696dba679e57f612ee95e707ccb05aff368b62b2802d5fb685403

Quelqu'un peut me aider à réparer mon code?

Répondre

0

Je pense que l'algorithme est construit de manière légèrement différente et/ou que la touche salt est interférée de manière différente.

1

Dans le code Java, vous n'utilisez pas l'IV.

Je ne suis pas assez avertis en C# pour vous aider directement, mais je peux donner quelques informations. Rijndael, alias "AES", crypte des blocs de 16 octets.

Pour crypter un message long (par exemple, votre message de test, lors de l'encodage, est long de 20 octets), Rijndael doit être invoqué plusieurs fois, avec un moyen d'enchaîner les invocations (aussi, il y a un "padding" la longueur est un multiple de 16). Le mode CBC effectue un tel chaînage.

En CBC, chaque bloc de données est combiné (XOR bit à bit) avec le bloc crypté précédent avant d'être lui-même crypté. Puisque le premier bloc de données n'a pas de bloc précédent, nous ajoutons un nouveau "bloc zéro" conventionnel appelé IV. Le IV devrait être choisi comme 16 octets aléatoires. La partie déchiffrante aura besoin de l'IV. L'intraveineuse n'a pas besoin d'être secrète (c'est la différence entre l'IV et la clé), donc elle est souvent transmise le long du message.

Dans votre code Java, vous ne spécifiez pas l'IV, vous créez simplement une variable appelée iv et ne l'utilisez pas. La mise en œuvre de Rijndael est donc indépendante. Les chances sont qu'il a généré un IV aléatoire. De même, vous ne donnez pas de IV à l'implémentation de Rijndael dans le code C#. Il est donc tout à fait plausible qu'une IV aléatoire ait été sélectionnée. Mais pas le même que celui du code Java, d'où les résultats distincts.

(Remarque: la chaîne d'entrée de 20 octets est complétée à 32 octets.Vous donnez deux "résultats" en hexadécimal, de longueur 32 octets chacun.C'est cohérent mais cela signifie que ces résultats n'incluent pas le IV - sinon ils auraient une longueur de 48 octets.)