How to decrypt RSA content in .NET?

后端 未结 1 817
感情败类
感情败类 2021-01-21 03:03

I am generating RSA private & public keys using OpenSSL, sending public key into HTML page to encrypt username & password (with JSEncrypt).The encrypted content sends to

相关标签:
1条回答
  • 2021-01-21 03:26

    The RSA format generate by OpenSSL is different with .NET,you should convert OpenSSL RSA xmlPrivateKey to XML format so it could be recognized by RSACryptoServiceProvider.

            private static RSACryptoServiceProvider DecodeRsaPrivateKey(string priKey)
            {
                var privkey = Convert.FromBase64String(priKey);
                byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
    
                // ---------  Set up stream to decode the asn.1 encoded RSA private key  ------
                var mem = new MemoryStream(privkey);
                var binr = new BinaryReader(mem);    //wrap Memory Stream with BinaryReader for easy reading
                try
                {
                    var twobytes = binr.ReadUInt16();
                    if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
                        binr.ReadByte();        //advance 1 byte
                    else if (twobytes == 0x8230)
                        binr.ReadInt16();       //advance 2 bytes
                    else
                        return null;
                    twobytes = binr.ReadUInt16();
                    if (twobytes != 0x0102) //version number
                        return null;
                    var bt = binr.ReadByte();
                    if (bt != 0x00)
                        return null;
    
                    //------  all private key components are Integer sequences ----
                    var elems = GetIntegerSize(binr);
                    MODULUS = binr.ReadBytes(elems);
    
                    elems = GetIntegerSize(binr);
                    E = binr.ReadBytes(elems);
    
                    elems = GetIntegerSize(binr);
                    D = binr.ReadBytes(elems);
    
                    elems = GetIntegerSize(binr);
                    P = binr.ReadBytes(elems);
    
                    elems = GetIntegerSize(binr);
                    Q = binr.ReadBytes(elems);
    
                    elems = GetIntegerSize(binr);
                    DP = binr.ReadBytes(elems);
    
                    elems = GetIntegerSize(binr);
                    DQ = binr.ReadBytes(elems);
    
                    elems = GetIntegerSize(binr);
                    IQ = binr.ReadBytes(elems);
    
                    // ------- create RSACryptoServiceProvider instance and initialize with public key -----
                    var rsa = new RSACryptoServiceProvider();
                    var rsAparams = new RSAParameters
                    {
                        Modulus = MODULUS,
                        Exponent = E,
                        D = D,
                        P = P,
                        Q = Q,
                        DP = DP,
                        DQ = DQ,
                        InverseQ = IQ
                    };
                    rsa.ImportParameters(rsAparams);
                    return rsa;
                }
                catch (Exception e)
                {
                    LogHelper.Logger.Error("DecodeRsaPrivateKey failed", e);
                    return null;
                }
                finally
                {
                    binr.Close();
                }
            }
    
    
    
            private static int GetIntegerSize(BinaryReader binary)
            {
                byte binaryReadByte = 0;
                var count = 0;
                binaryReadByte = binary.ReadByte();
                if (binaryReadByte != 0x02)        //expect integer
                    return 0;
                binaryReadByte = binary.ReadByte();
                if (binaryReadByte == 0x81)
                {
                    count = binary.ReadByte(); // data size in next byte
                }
                else
                {
                    if (binaryReadByte == 0x82)
                    {
                        var highbyte = binary.ReadByte();
                        var lowbyte = binary.ReadByte();
                        byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                        count = BitConverter.ToInt32(modint, 0);
                    }
                    else
                    {
                        count = binaryReadByte; // we already have the data size
                    }
                }
                while (binary.ReadByte() == 0x00)
                {    //remove high order zeros in data
                    count -= 1;
                }
                binary.BaseStream.Seek(-1, SeekOrigin.Current);        //last ReadByte wasn't a removed zero, so back up a byte
                return count;
            }
    

    So the RSACryptoServiceProvider can decrypt the original context.

    0 讨论(0)
提交回复
热议问题