C# BouncyCastle - le Cryptage RSA, avec les clés Publiques/Privées

J'ai besoin de crypter les données en C# pour passer à Java. Le code Java appartient à une 3ème partie, mais j'ai donné le code source, donc j'ai décidé que le Java utilise le Château Gonflable libs, je vais utiliser le C# port.

Déchiffrement fonctionne très bien. Cependant, le décryptage ne fonctionne que lorsque j'utilise le crypter à l'aide de la clé privée, et non pas avec la clé publique. Lors de l'utilisation de la clé publique, le décryptage échoue avec unknown block type.

Évidemment le chiffrement à l'intérieur de la RsaEncryptWithPrivate utilise la clé publique pour le chiffrement, donc je ne comprends pas pourquoi les deux méthodes de cryptage ne sont pas fonctionnellement identiques:

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
}

Incidemment, la Java de déchiffrement des expositions de la même question - quand chiffré avec la clé publique, il échoue.

Je suis très nouveau à la cryptographie, donc je suis sûr que je suis en train de faire quelque chose de très simple de mal dans le RsaEncryptWithPublic méthode.

EDIT:

J'ai aussi ajouté un test unitaire qui prouve que la clé publique est égal à la clé publique qui est extraite à partir de la clé privée:

    [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;
} 
J'ai été en utilisant une mauvaise Clé Publique.. et le test qui s'est avéré le Privé et le Public, clés de correspondance a été à l'aide de la Clé Publique correcte. La une\bove code fonctionne parfaitement comme est, aussi longtemps que vous obtenez les clés de droite!

OriginalL'auteur scudsucker | 2015-01-22