У меня есть требование, при котором шифрование выполняется в Java, а дешифрование - в. net, поскольку существует две системы. Я изо всех сил пытаюсь выполнить расшифровку асимметрии c.
Вкл. Java, применяется шифрование асимметрии c с помощью "RSA / ECB / PKCS1Padding"
public String encryptSymmKey() throws Exception
{
Cipher asymmCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
asymmCipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey());
byte[] encSymmKeyBytes = asymmCipher.doFinal(symmKey.getEncoded());
String encSymmKeyString= new String(Base64.encode(encSymmKeyBytes));
encSymmKeyString = URLEncoder.encode(encSymmKeyString, "UTF-8");
return(encSymmKeyString);
}
Моя задача расшифровать его и вернуть реальный ключ симметрии c, чтобы я мог использовать его для расшифровки Symmetri c. У меня есть файл PEM и пароль base64. Я попытался расшифровать в двух подходах через BouncyCastle и RSA (System.Security.Cryptography).
Подход 1: - RSA
Код: -
public class MyRSAParams
{
public static MyRSAParams fromRSAParameters(RSAParameters key)
{
var ret = new MyRSAParams();
ret.Modulus = new BigInteger(key.Modulus.Reverse().Concat(new byte[] { 0 }).ToArray());
ret.privExponent = new BigInteger(key.D.Reverse().Concat(new byte[] { 0 }).ToArray());
ret.pubExponent = new BigInteger(key.Exponent.Reverse().Concat(new byte[] { 0 }).ToArray());
return ret;
}
public BigInteger Modulus;
public BigInteger privExponent;
public BigInteger pubExponent;
}
public byte[] plainDecryptPriv(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.privExponent, myKey.Modulus);
}
private byte[] rsaOperation(byte[] data, BigInteger exp, BigInteger mod)
{
BigInteger bData = new BigInteger(
data //our data block
.Reverse() //BigInteger has another byte order
.Concat(new byte[] { 0 }) // append 0 so we are allways handling positive numbers
.ToArray() // constructor wants an array
);
return
BigInteger.ModPow(bData, exp, mod) // the RSA operation itself
.ToByteArray() //make bytes from BigInteger
.Reverse() // back to "normal" byte order
.ToArray(); // return as byte array
/*
*
* A few words on Padding:
*
* you will want to strip padding after decryption or apply before encryption
*
*/
}
Основной лог дешифрования c: -
byte[] cipherBytes = System.Convert.FromBase64String(cipherText);
using (RSA rsa = RSA.Create())
using (var stream = File.OpenRead(<PEM FILE>))
using (var reader = new PemReader(stream))
{
var rsaParameters = reader.ReadRsaKey();
rsa.ImportParameters(rsaParameters);
}
var decBytes = plainDecryptPriv(cipherBytes, rsa.ExportParameters(true));
var decData = decBytes.SkipWhile(x => x != 0).Skip(1).ToArray();
var result = System.Text.Encoding.Default.GetString(decData);
Результат: - I получил строку, но она неверна
"\0�{]*ɠ8��+\0gNqMNm�hZ�\u001et\u0010��\u0010\u00161��u,*O��a�\u0003`8Iŝ���`]\u0003�a��A\\�\fiK�12��M� qOF�\u000e��Q\"Eg���3_�;��u�\u0011U\u0001����t�`����!56�,\a{�Z��\u0006|��K2}�HA�\b_�Ix\u0001]�ܳ��CW�;q\u001c�nJ<A�L�$�NG�u%\u001e4N�x��dl\u0011bS��X\u000f\u0006���\u0011�)�d�RW�E�\tB���5|��8���\u0014�(u]�ċ�o�*\u0016���P��z�\v����lء\u0017WYj�D2GT�t\u000f��p\u000f"
Я также пытался с rsa.Decrypt(cipherBytes, false)
и всеми другими RSAEncryptionPadding
параметрами, я вижу ошибку:
Параметр неверный
Подход 2: - BouncyCastle
Код: -
using (var reader = File.OpenText(<PEM File>))
{
keyPair = (AsymmetricCipherKeyPair)new
Org.BouncyCastle.OpenSsl.PemReader(reader)).ReadObject();
RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)keyPair.Private;
RsaKeyParameters privParameters = new RsaPrivateCrtKeyParameters(privKey.Modulus,
privKey.PublicExponent, privKey.Exponent, privKey.P, privKey.Q, privKey.DP, privKey.DQ,
privKey.QInv);
IAsymmetricBlockCipher eng = new Pkcs1Encoding(new RsaEngine());
eng.Init(false, privParameters);
byte[] encdata = System.Convert.FromBase64String(ks);
encdata = eng.ProcessBlock(encdata, 0, encdata.Length);
string finalResult = Encoding.UTF8.GetString(encdata);
}
Результат: - Я получаю ошибку в eng.ProcessBlock
, говоря
блок неправильный
Я также добавил пароль к PemReader
, и при попытке он дал тот же результат.
Я убедился, что я использую правильный файл PEM. Я использую asp. net базовая версия 3.0.
РЕДАКТИРОВАТЬ: -