Асимметрия c Расшифровка RSA / ECB / PKCS1Вкладка в. net с файлом PEM - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть требование, при котором шифрование выполняется в 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.

РЕДАКТИРОВАТЬ: -

I see the bitlength of Modulus being 2048 which is 256 bytes, same as the cipher bytes

...