2015-08-19 26 views
7

Siamo in procinto di svuotare molte funzionalità condivise nel nostro sistema e portarlo alle librerie PCL. Sto riscontrando un problema con PCLCrypto. Sto prendendo alcuni dati esistenti nel nostro database, e sto provando a decodificarlo con lo stesso algoritmo. Ricevo il valore, ma alla fine ci sono 16 byte extra che sono solo spazzatura.System.Security.Cryptography vs PCLCrypto

vedi codice qui sotto: Vecchio algoritmo utilizzando System.Security.Cryptography

public static string SymmetricEncrypt(this string plaintext, string key, SymmetricAlgorithm algorithm) 
{ 
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); 
    byte[] plainTextBuffer = Encoding.UTF8.GetBytes(plaintext); 

    var symmetricAlgorithm = new AesCryptoServiceProvider(); 
    symmetricAlgorithm.Key = keyBuffer; 
    symmetricAlgorithm.Mode = CipherMode.ECB; 

    var encryptor = symmetricAlgorithm.CreateEncryptor(); 
    byte[] cipherBuffer = encryptor.TransformFinalBlock(plainTextBuffer, 0, plainTextBuffer.Length); 
    symmetricAlgorithm.Clear(); 

    return Convert.ToBase64String(cipherBuffer); 
} 


public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm) 
    { 
     byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); 
     byte[] cipherTextBuffer = Convert.FromBase64String(cipherText); 
     var symmetricAlgorithm = new AesCryptoServiceProvider(); 
     symmetricAlgorithm.Key = keyBuffer; 
     symmetricAlgorithm.Mode = CipherMode.ECB; 

     var decryptor = symmetricAlgorithm.CreateDecryptor(); 
     byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length); 
     symmetricAlgorithm.Clear(); 

     return Encoding.Default.GetString(plainTextBuffer); 
    } 

decrittografia utilizzando PCLCrypto

public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm) { 
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); 
    byte[] cipherTextBuffer = Convert.FromBase64String(cipherText); 

    ISymmetricKeyAlgorithmProvider symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.SymmetricAlgorithm.AesEcb); 

    var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyBuffer); 
    var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey); 
    byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length); 
    return UTF8Encoding.UTF8.GetString(plainTextBuffer, 0, plainTextBuffer.Length); 
} 

Utilizzando la vecchia versione: plainTextBuffer è di 16 byte, nuova versione è 32 byte.

Help!

+1

È un progetto GitHub attivo quindi è necessario segnalare un problema lì per raggiungere i suoi autori. –

+0

Nella riga inferiore del codice postato, presumo che intendiate digitare plainTextBuffer, non plainText. La difficoltà qui è che il progetto GitHub sta semplicemente accedendo ad altre API e non implementa il proprio AES. Ma detto questo, non riesco a trovare alcun motivo per questo comportamento nel repository né nel tuo codice. Strano, dichiari plainTextBuffer in una chiamata a TransformFinalBlock, una funzione che pensavo non fosse mai più grande della dimensione effettiva del blocco dell'algoritmo, eppure hai quei byte extra. Mi dispiace dire che sono perplesso. – WDS

risposta

4

Questo sembra un problema di riempimento.

Guardando all'origine per la classe base SymmetricAlgorithm in .NET, che è la base di AesCryptoServiceProvider, il padding predefinito è PaddingMode.PKCS7. Non sembra che abbia definito una modalità di riempimento, quindi suppongo che il valore predefinito si applichi ancora.

Anche se non ho ancora utilizzato la libreria PCLCrypto, dando un'occhiata a github ci sono un paio di algoritmi AesEcb: AesEcb e AesEcbPkcs7. L'assenza di una modalità di riempimento dal nome di AesEcb implicherebbe a me che non ha padding (e quindi non ha rimosso alcuna padding), che sarebbe l'equivalente di PaddingMode.None nelle librerie .NET.

Provare a utilizzare l'algoritmo PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7 in PCLCrypto e verificare se questo rimuove il padding visualizzato alla fine dell'output.

Aggiornamento

Ho appena provato questo, e sembra funzionare correttamente e rimuovere l'imbottitura si sarebbe vedendo:

public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm) { 
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); 
    byte[] cipherTextBuffer = Convert.FromBase64String(cipherText); 

    ISymmetricKeyAlgorithmProvider symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7); 

    var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyBuffer); 
    var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey); 
    byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length); 
    return UTF8Encoding.UTF8.GetString(plainTextBuffer, 0, plainTextBuffer.Length); 
}

L'unico cambiamento stava cambiando l'algoritmo PCLCrypto.SymmetricAlgorithm.AesEcb a PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7

+0

Sei il mio eroe. Grazie mille. –