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;
}
OriginalL'auteur scudsucker | 2015-01-22
Vous devez vous connecter pour publier un commentaire.
Il y a quelques erreurs dans l'OP du code. J'ai fait quelques changements. Voici ce que j'ai obtenu en cours d'exécution.
Avez-vous eu une erreur " illegal objet dans GetInstance: Org.BouncyCastle.Asn1.DerSequence " avec ce code? Je suis en train de tester la BouncyCastle pour voir comment il fonctionne et lorsque j'exécute le code ci-dessus j'ai ce message d'erreur.
Je pense qu'il pourrait être causé par un changement de version. Vous pouvez essayer une version proche de mon post du temps et de remonter la trace de voir ce qui est l'API de changement.
OriginalL'auteur Morio
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.
Le code ci-dessus fonctionne parfaitement comme est, aussi longtemps que vous obtenez les clés de droite!
OriginalL'auteur scudsucker
J'ai essayé @Mario est une solution, mais a été d'obtenir quelques exceptions près. Le premier a été
-----END PUBLIC KEY not found
Qui j'ai été en mesure de corriger la mise en forme à la fois des touches correctement
La deuxième erreur a été tout en essayant de déchiffrer le texte.
Unable to cast object of type 'Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters' to type 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair'.
Qui je résolus par la coulée du type approprié.
OriginalL'auteur hatsrumandcode