Ottenere SlowAES e RijndaelGestione gestita in .NET per giocare insieme

Sto cercando di configurare la crittografia / decrittografia AES utilizzando la libreria javascript SlowAES e la class RijndaelManaged in .NET.

Ho scelto questo metodo dopo aver letto questo post , dove Cheeso è riuscito a far giocare questi due metodi di crittografia

“Nei miei test degli SLP-COM avvolti, ho usato la modalità CBC e la crittografia era completamente compatibile con la class RijndaelManaged in .NET” – Cheeso

Ho preso il codice javascript dal componente Script di Windows di Cheeso, le ultime librerie di slowaes e utilizzando il seguente script javascript per testare:

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 + "
original:" + message + "
Cypher:" + result + "
Decrypted:" + decrypted + "
IV(): " + get_IV());

Sto ottenendo il seguente risultato:

     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 

    Ho modificato il seguente esempio trovato su MSDN per cercare di far corrispondere la crittografia 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); } } 

    Guarda l’array di byte:

     - 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 

    Ho provato tutte le opzioni di riempimento con la class .NET gestita, tuttavia non riesco a far corrispondere le uscite crittografate. Qualcuno può aiutarmi?

    Grazie,

    peso

    forse posso aiutare

    Ho preso il tuo codice C # e l’ho leggermente modificato. Il codice C # che uso, nella sua interezza, è:

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

    compilare quanto sopra con

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

    Io uso il file slowAES.wsc dall'altro post che hai fatto riferimento, con 2 modifiche: non chiamo getPaddedBlock () per la chiave nei metodi EncryptString o DecryptString (). Questo ha davvero bisogno di un PBKDF ma non preoccupiamoci di questo ora. Ecco come appare EncryptString modificato:

     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']; } 

    Ciò significa che devi usare una passphrase che è esattamente la lunghezza richiesta dal keysize. Se si utilizza AES256, passare una stringa di 32 caratteri (32 * 8 = 256 bit). Sembra che tu l'abbia già capito.

    Anche il client del componente WSC è Javascript (sebbene possa essere qualsiasi linguaggio COM). Ecco cosa ho usato.

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

    Se eseguo questo codice, Javascript e C # producono lo stesso testo cifrato per un testo in chiaro di "watson?", Utilizzando AES256, passphrase di 12345678901234567890123456789012 e un IV di 16 byte di zero. Il testo cifrato generato è:

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

    Decodifica con successo in entrambi i casi.

    EDIT : Anche se ho impacchettato la crittografia slowAES in un WSC, sarà interoperabile anche all'esterno dell'ambiente COM. La parte WSC non è necessaria per questa domanda, ma era necessario dimostrare la risposta a una domanda precedente, che era " come posso far interagire VBScript e .NET AES? "

    EDIT2 : è disponibile il codice sorgente che dimostra l'interoperabilità AES tra Javascript o VBScript e .NET. Ho esteso l'esempio di base fornito qui per produrre app di prova in 3 lingue: C #, Javascript e VBScript. Prendono tutti lo stesso insieme di argomenti. Ognuno di essi utilizza una funzione di derivazione della chiave conforms a RFC2898. È ansible specificare la password, salt, IV e plaintext, nonché il numero di iterazioni RFC2898 da utilizzare nel PBKDF2. È ansible verificare facilmente che il testo cifrato sia lo stesso per ciascuno di questi programmi di test. Forse l'esempio sarà utile per qualcuno.

    Edit3
    una buona lettura: la crittografia Javascript è considerata dannosa.