Tôi cần mã hóa dữ liệu trong C# để chuyển nó sang Java. Mã Java thuộc về bên thứ 3 nhưng tôi đã được cung cấp nguồn có liên quan, vì vậy tôi đã quyết định rằng khi Java sử dụng libs Bouncy Castle, tôi sẽ sử dụng cổng C#.C# BouncyCastle - Mã hóa RSA với khóa công khai/riêng tư
Giải mã hoạt động tốt. Tuy nhiên, giải mã chỉ hoạt động khi tôi sử dụng mã hóa bằng khóa riêng, chứ không phải bằng khóa công cộng. Khi sử dụng khóa công khai, giải mã không thành công với unknown block type
.
Rõ ràng là mã hóa bên trong RsaEncryptWithPrivate
sử dụng khóa công khai khi mã hóa, vì vậy tôi không hiểu tại sao hai phương pháp mã hóa không phải là chức năng giống hệt nhau:
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
}
Ngẫu giải mã Java thể hiện cùng một vấn đề - khi mã hóa chỉ với khóa công khai, nó không thành công.
Tôi rất mới về mật mã, vì vậy tôi chắc chắn mình đang làm điều gì đó rất đơn giản sai trong phương thức RsaEncryptWithPublic
.
EDIT:
Tôi cũng đã thêm một thử nghiệm đơn vị trong đó chứng minh rằng khóa công khai bằng với khóa công khai được chiết xuất từ khóa riêng:
[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;
}
Tôi đã sử dụng khóa công khai không chính xác .. và kiểm tra chứng minh khóa cá nhân và khóa công khai phù hợp đang sử dụng Khóa công khai chính xác. Mã \ bove hoạt động hoàn hảo, miễn là bạn nhận được các phím đúng! – scudsucker