2015-01-22 59 views
15

Ho bisogno di crittografare i dati in C# per passarlo a Java. Il codice Java appartiene a una terza parte, ma mi è stata data la fonte pertinente, quindi ho deciso che siccome Java usa le librerie Bouncy Castle, userò la porta C#.C# BouncyCastle - Crittografia RSA con chiavi pubbliche/private

La decifratura funziona correttamente. Tuttavia, la decrittografia funziona solo quando utilizzo la crittografia utilizzando la chiave privata e non con la chiave pubblica. Quando si utilizza la chiave pubblica, la decifratura fallisce con unknown block type.

Ovviamente la crittografia all'interno del RsaEncryptWithPrivate utilizza la chiave pubblica per crittografare, quindi non capisco il motivo per cui i due metodi di crittografia non sono funzionalmente identici:

using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.Crypto.Encodings; 
using Org.BouncyCastle.Crypto.Engines; 
using Org.BouncyCastle.OpenSsl; 

public class EncryptionClass 
{  
    public string RsaEncryptWithPublic(string clearText 
     , string publicKey) 
    { 
     var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText); 

     var encryptEngine = new Pkcs1Encoding(new RsaEngine()); 

     using (var txtreader = new StringReader(publicKey)) 
     { 
      var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject(); 

      encryptEngine.Init(true, keyParameter); 
     } 

     var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length)); 
     return encrypted; 

    } 

    public string RsaEncryptWithPrivate(string clearText 
     , string privateKey) 
    { 
     var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText); 

     var encryptEngine = new Pkcs1Encoding(new RsaEngine()); 

     using (var txtreader = new StringReader(privateKey)) 
     { 
      var keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); 

      encryptEngine.Init(true, keyPair.Public); 
     } 

     var encrypted= Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length)); 
     return encrypted; 
    } 


    // Decryption: 

    public string RsaDecrypt(string base64Input 
     , string privateKey) 
    { 
     var bytesToDecrypt = Convert.FromBase64String(base64Input); 

     //get a stream from the string 
     AsymmetricCipherKeyPair keyPair; 
     var decryptEngine = new Pkcs1Encoding(new RsaEngine()); 

     using (var txtreader = new StringReader(privateKey)) 
     { 
      keyPair = (AsymmetricCipherKeyPair) new PemReader(txtreader).ReadObject(); 

      decryptEngine.Init(false, keyPair.Private); 
     } 

     var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length)); 
     return decrypted; 
    } 
} 

// In my test project 

    [Test()] 
    public void EncryptTest() 
    { 
     // Set up 
     var input = "Perceived determine departure explained no forfeited"; 
     var enc = new EncryptionClass(); 
     var publicKey = "-----BEGIN PUBLIC KEY----- // SNIPPED // -----END PUBLIC KEY-----"; 
     var privateKey = "-----BEGIN PRIVATE KEY----- // SNIPPED // -----END PRIVATE KEY-----"; 

     // Encrypt it 
     var encryptedWithPublic = enc.RsaEncryptWithPublic(input, publicKey); 

     var encryptedWithPrivate = enc.RsaEncryptWithPrivate(input, privateKey); 

     // Decrypt 
     var outputWithPublic = payUEnc.RsaDecrypt(encryptedWithPrivate, privateKey); 
     // Throws error: "unknown block type" 

     var outputWithPrivate = payUEnc.RsaDecrypt(encryptedWithPrivate, _privateKey); 
     // returns the correct decrypted text, "Perceived determine departure explained no forfeited" 

     // Assertion 
     Assert.AreEqual(outputWithPrivate, input); // This is true 
    } 

Per inciso la decrittografia Java presenta lo stesso problema - quando criptato con la sola chiave pubblica, fallisce.

Sono molto nuovo alla crittografia, quindi sono sicuro che sto facendo qualcosa di molto semplice nel metodo RsaEncryptWithPublic.

EDIT:

Ho anche aggiunto una prova di unità che dimostra che la chiave pubblica è uguale alla chiave pubblica che viene estratto dalla chiave privata:

[Test()] 
    public void EncryptCompareTest() 
    { 
     AsymmetricKeyParameter keyParameterFromPub; 
     AsymmetricKeyParameter keyParameterFromPriv; 
     AsymmetricCipherKeyPair keyPair; 

     using (var txtreader = new StringReader(_publicKey)) 
     { 
      keyParameterFromPub = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject(); 
     } 

     using (var txtreader = new StringReader(_privateKey)) 
     { 
      keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); 
      keyParameterFromPriv = keyPair.Public; 
     } 

     Assert.AreEqual(keyParameterFromPub, keyParameterFromPriv); // returns true; 

    } 
+0

Stavo usando una chiave pubblica errata .. e il test che ha provato che le chiavi private e pubbliche corrispondevano stava usando la chiave pubblica corretta. Il codice a \ bove funziona perfettamente come è, a patto che tu abbia le chiavi giuste! – scudsucker

risposta

2

stavo usando un errato Chiave pubblica .. e il test che ha dimostrato che le chiavi private e pubbliche corrispondevano stava usando la chiave pubblica corretta.

Il codice sopra funziona perfettamente come è, finché si ottiene le chiavi giusto!

13

Ci sono alcuni errori nel codice OP. Ho apportato poche modifiche. Ecco cosa ho ottenuto in esecuzione.

public class TFRSAEncryption 
{ 
    public string RsaEncryptWithPublic(string clearText, string publicKey) 
    { 
     var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText); 

     var encryptEngine = new Pkcs1Encoding(new RsaEngine()); 

     using (var txtreader = new StringReader(publicKey)) 
     { 
      var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject(); 

      encryptEngine.Init(true, keyParameter); 
     } 

     var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length)); 
     return encrypted; 

    } 

    public string RsaEncryptWithPrivate(string clearText, string privateKey) 
    { 
     var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText); 

     var encryptEngine = new Pkcs1Encoding(new RsaEngine()); 

     using (var txtreader = new StringReader(privateKey)) 
     { 
      var keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); 

      encryptEngine.Init(true, keyPair.Private); 
     } 

     var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length)); 
     return encrypted; 
    } 


    // Decryption: 

    public string RsaDecryptWithPrivate(string base64Input, string privateKey) 
    { 
     var bytesToDecrypt = Convert.FromBase64String(base64Input); 

     AsymmetricCipherKeyPair keyPair; 
     var decryptEngine = new Pkcs1Encoding(new RsaEngine()); 

     using (var txtreader = new StringReader(privateKey)) 
     { 
      keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); 

      decryptEngine.Init(false, keyPair.Private); 
     } 

     var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length)); 
     return decrypted; 
    } 

    public string RsaDecryptWithPublic(string base64Input, string publicKey) 
    { 
     var bytesToDecrypt = Convert.FromBase64String(base64Input); 

     var decryptEngine = new Pkcs1Encoding(new RsaEngine()); 

     using (var txtreader = new StringReader(publicKey)) 
     { 
      var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject(); 

      decryptEngine.Init(false, keyParameter); 
     } 

     var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length)); 
     return decrypted; 
    } 
} 

class Program 
{ 

    static void Main(string[] args) 
    { 
     // Set up 
     var input = "Perceived determine departure explained no forfeited"; 
     var enc = new TFRSAEncryption(); 
     var publicKey = "-----BEGIN PUBLIC KEY----- // Base64 string omitted // -----END PUBLIC KEY-----"; 
     var privateKey = "-----BEGIN PRIVATE KEY----- // Base64 string omitted// -----END PRIVATE KEY-----"; 

     // Encrypt it 
     var encryptedWithPublic = enc.RsaEncryptWithPublic(input, publicKey); 

     var encryptedWithPrivate = enc.RsaEncryptWithPrivate(input, privateKey); 

     // Decrypt 
     var output1 = enc.RsaDecryptWithPrivate(encryptedWithPublic, privateKey); 

     var output2 = enc.RsaDecryptWithPublic(encryptedWithPrivate, publicKey); 

     Console.WriteLine(output1 == output2 && output2 == input); 

     Console.Read(); 
    } 
} 
+0

Grazie! Apprezzo il vostro aiuto –