PHP';s openssl#使用字符串登录C#

PHP';s openssl#使用字符串登录C#,c#,C#,在C#中有没有一种简单的方法可以做到这一点 openssl\u符号($input、$output、$privateKey、openssl\u ALGO\u SHA1) $input是要签名的字符串 $output-如果调用成功,将在此变量中返回签名。它是一个字节[] $privateKey是PEM私钥(字符串) 参考: 我从XML中获取输入字符串,它是扁平的,如下所示: qux1qux2 我从XML中标记的内容中获取privateKey字符串: 福 酒吧 -----开始RSA私钥---

在C#中有没有一种简单的方法可以做到这一点

openssl\u符号($input、$output、$privateKey、openssl\u ALGO\u SHA1)
  • $input
    是要签名的字符串
  • $output
    -如果调用成功,将在此变量中返回签名。它是一个字节[]
  • $privateKey
    是PEM私钥(字符串)
参考:

我从XML中获取
输入
字符串,它是扁平的,如下所示:

qux1qux2
我从XML中
标记的内容中获取
privateKey
字符串:


福
酒吧
-----开始RSA私钥-----
miibogibaajbamo8ssypcvfbdgcqfv8o8uznvcxo6fwukmbdfognia5yqktjc8i
VIYt6oXLfes+q5i+4oqwb6mjgtizvcjmcl8caqmcqcg0ttutlh2k16rha9uxfyz
TRSKUIFA9YSBASDLMWCMAJVWBSCJCXDECXFWJVCFTO5FFF6PIIGPACHUZLSO8XB
AiEA9vjXy5u74OBS3ekQdMuKrUv5fi6z+ECHHCLVTFWHMCIQDROMYPPTXAMDDY
24QPFZQM9ORGXGEQCG0VVOLCAQUJQIHAKSL5TJN0PXQ4ELGCVIHSCJDUP7JZVAR
功能1VBJNG9A3AI8CICRJS1BRLOZ0CXG5IXKRCLZQHEWIYJMSGAECCYSMCIEFT
oGduMC3vOMtKHEo8SAfDFeirfubo+FAZteQ0pyFF
-----结束RSA私钥-----

一点也不容易:

  • 首先,我需要将输入字符串转换为字节[]

        ASCIIEncoding ByteConverter = new ASCIIEncoding();
        byte[] inputBytes = ByteConverter.GetBytes(input);
    
  • 计算它的SHA1散列

        byte[] inputHash = new SHA1CryptoServiceProvider().ComputeHash(inputBytes);
    
  • 删除RSA私钥的开头和结尾,并将其转换为字节[]

        byte[] privateKeyBytes = Convert.FromBase64String(privateKey
            .Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty)
            .Replace("-----END RSA PRIVATE KEY-----", string.Empty)
            .Replace("\n", string.Empty));
    
  • 然后我必须从
    privateKeyBytes
    创建一个
    rsacyptoserviceprovider
    ,但我必须使用互联网上的一个复杂类:

        RSACryptoServiceProvider rsa = RSAUtils.DecodeRSAPrivateKey(privateKeyBytes);
                                       // ^
                                       // Found on Internet
    
    public class RSAUtils
    {
        public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
        {
            byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
    
            // --------- Set up stream to decode the asn.1 encoded RSA private key ------
            MemoryStream mem = new MemoryStream(privkey);
            BinaryReader binr = new BinaryReader(mem);  //wrap Memory Stream with BinaryReader for easy reading
            byte bt = 0;
            ushort twobytes = 0;
            int elems = 0;
            try
            {
                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;
                bt = binr.ReadByte();
                if (bt != 0x00)
                    return null;
    
    
                //------ all private key components are Integer sequences ----
                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 -----
                CspParameters CspParameters = new CspParameters();
                CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);
                RSAParameters RSAparams = new RSAParameters();
                RSAparams.Modulus = MODULUS;
                RSAparams.Exponent = E;
                RSAparams.D = D;
                RSAparams.P = P;
                RSAparams.Q = Q;
                RSAparams.DP = DP;
                RSAparams.DQ = DQ;
                RSAparams.InverseQ = IQ;
                RSA.ImportParameters(RSAparams);
                return RSA;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                binr.Close();
            }
        }
    
        private static int GetIntegerSize(BinaryReader binr)
        {
            byte bt = 0;
            byte lowbyte = 0x00;
            byte highbyte = 0x00;
            int count = 0;
            bt = binr.ReadByte();
            if (bt != 0x02)      //expect integer
                return 0;
            bt = binr.ReadByte();
    
            if (bt == 0x81)
                count = binr.ReadByte();    // data size in next byte
            else
                if (bt == 0x82)
                {
                    highbyte = binr.ReadByte();    // data size in next 2 bytes
                    lowbyte = binr.ReadByte();
                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                    count = BitConverter.ToInt32(modint, 0);
                }
                else
                {
                    count = bt;      // we already have the data size
                }
    
            while (binr.ReadByte() == 0x00)
            {    //remove high order zeros in data
                count -= 1;
            }
            binr.BaseStream.Seek(-1, SeekOrigin.Current);        //last ReadByte wasn't a removed zero, so back up a byte
            return count;
        }
    
    }
    
  • 然后我终于可以签字了

        byte[] output = rsa.SignHash(inputHash, "SHA1");
    
  • 在Internet上找到的代码:

        RSACryptoServiceProvider rsa = RSAUtils.DecodeRSAPrivateKey(privateKeyBytes);
                                       // ^
                                       // Found on Internet
    
    public class RSAUtils
    {
        public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
        {
            byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
    
            // --------- Set up stream to decode the asn.1 encoded RSA private key ------
            MemoryStream mem = new MemoryStream(privkey);
            BinaryReader binr = new BinaryReader(mem);  //wrap Memory Stream with BinaryReader for easy reading
            byte bt = 0;
            ushort twobytes = 0;
            int elems = 0;
            try
            {
                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;
                bt = binr.ReadByte();
                if (bt != 0x00)
                    return null;
    
    
                //------ all private key components are Integer sequences ----
                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 -----
                CspParameters CspParameters = new CspParameters();
                CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);
                RSAParameters RSAparams = new RSAParameters();
                RSAparams.Modulus = MODULUS;
                RSAparams.Exponent = E;
                RSAparams.D = D;
                RSAparams.P = P;
                RSAparams.Q = Q;
                RSAparams.DP = DP;
                RSAparams.DQ = DQ;
                RSAparams.InverseQ = IQ;
                RSA.ImportParameters(RSAparams);
                return RSA;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                binr.Close();
            }
        }
    
        private static int GetIntegerSize(BinaryReader binr)
        {
            byte bt = 0;
            byte lowbyte = 0x00;
            byte highbyte = 0x00;
            int count = 0;
            bt = binr.ReadByte();
            if (bt != 0x02)      //expect integer
                return 0;
            bt = binr.ReadByte();
    
            if (bt == 0x81)
                count = binr.ReadByte();    // data size in next byte
            else
                if (bt == 0x82)
                {
                    highbyte = binr.ReadByte();    // data size in next 2 bytes
                    lowbyte = binr.ReadByte();
                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                    count = BitConverter.ToInt32(modint, 0);
                }
                else
                {
                    count = bt;      // we already have the data size
                }
    
            while (binr.ReadByte() == 0x00)
            {    //remove high order zeros in data
                count -= 1;
            }
            binr.BaseStream.Seek(-1, SeekOrigin.Current);        //last ReadByte wasn't a removed zero, so back up a byte
            return count;
        }
    
    }
    




    测试它是否有效

    Php测试

    $input = "<DD><RE>97975000-5</RE><TD>33</TD><F>27</F><FE>2003-09-08</FE><RR>8414240-9</RR><RSR>JORGE GONZALEZ LTDA</RSR><MNT>502946</MNT><IT1>Cajon AFECTO</IT1><CAF version=\"1.0\"><DA><RE>97975000-5</RE><RS>RUT DE PRUEBA</RS><TD>33</TD><RNG><D>1</D><H>200</H></RNG><FA>2003-09-04</FA><RSAPK><M>0a4O6Kbx8Qj3K4iWSP4w7KneZYeJ+g/prihYtIEolKt3cykSxl1zO8vSXu397QhTmsX7SBEudTUx++2zDXBhZw==</M><E>Aw==</E></RSAPK><IDK>100</IDK></DA><FRMA algoritmo=\"SHA1withRSA\">g1AQX0sy8NJugX52k2hTJEZAE9Cuul6pqYBdFxj1N17umW7zG/hAavCALKByHzdYAfZ3LhGTXCai5zNxOo4lDQ==</FRMA></CAF><TSTED>2003-09-08T12:28:31</TSTED></DD>";
    $privateKey = "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBANGuDuim8fEI9yuIlkj+MOyp3mWHifoP6a4oWLSBKJSrd3MpEsZdczvL0l7t/e0IU5rF+0gRLnU1Mfvtsw1wYWcCAQMCQQCLyV9FxKFLW09yWw7bVCCdxpRDr7FRX/EexZB4VhsNxm/vtJfDZyYle0Lfy42LlcsXxPm1w6Q6NnjuW+AeBy67AiEA7iMi5q5xjswqq+49RP55o//jqdZL/pC9rdnUKxsNRMMCIQDhaHdIctErN2hCIP9knS3+9zra4R+5jSXOvI+3xVhWjQIhAJ7CF0R0S7SIHHKe04NUURf/7RvkMqm108k74sdnXi3XAiEAlkWk2vc2HM+a1sCqQxNz/098ketqe7NuidMKeoOQObMCIQCkFAMS9IcPcMjk7zI2r/4EEW63PSXyN7MFAX7TYe25mw==\n-----END RSA PRIVATE KEY-----";
    openssl_sign($input, $output, $privateKey, OPENSSL_ALGO_SHA1);
    echo(base64_encode($output));
    
    string input = "<DD><RE>97975000-5</RE><TD>33</TD><F>27</F><FE>2003-09-08</FE><RR>8414240-9</RR><RSR>JORGE GONZALEZ LTDA</RSR><MNT>502946</MNT><IT1>Cajon AFECTO</IT1><CAF version=\"1.0\"><DA><RE>97975000-5</RE><RS>RUT DE PRUEBA</RS><TD>33</TD><RNG><D>1</D><H>200</H></RNG><FA>2003-09-04</FA><RSAPK><M>0a4O6Kbx8Qj3K4iWSP4w7KneZYeJ+g/prihYtIEolKt3cykSxl1zO8vSXu397QhTmsX7SBEudTUx++2zDXBhZw==</M><E>Aw==</E></RSAPK><IDK>100</IDK></DA><FRMA algoritmo=\"SHA1withRSA\">g1AQX0sy8NJugX52k2hTJEZAE9Cuul6pqYBdFxj1N17umW7zG/hAavCALKByHzdYAfZ3LhGTXCai5zNxOo4lDQ==</FRMA></CAF><TSTED>2003-09-08T12:28:31</TSTED></DD>";
    string privateKey = "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBANGuDuim8fEI9yuIlkj+MOyp3mWHifoP6a4oWLSBKJSrd3MpEsZdczvL0l7t/e0IU5rF+0gRLnU1Mfvtsw1wYWcCAQMCQQCLyV9FxKFLW09yWw7bVCCdxpRDr7FRX/EexZB4VhsNxm/vtJfDZyYle0Lfy42LlcsXxPm1w6Q6NnjuW+AeBy67AiEA7iMi5q5xjswqq+49RP55o//jqdZL/pC9rdnUKxsNRMMCIQDhaHdIctErN2hCIP9knS3+9zra4R+5jSXOvI+3xVhWjQIhAJ7CF0R0S7SIHHKe04NUURf/7RvkMqm108k74sdnXi3XAiEAlkWk2vc2HM+a1sCqQxNz/098ketqe7NuidMKeoOQObMCIQCkFAMS9IcPcMjk7zI2r/4EEW63PSXyN7MFAX7TYe25mw==\n-----END RSA PRIVATE KEY-----";
    
    ASCIIEncoding ByteConverter = new ASCIIEncoding();
    byte[] inputBytes = ByteConverter.GetBytes(input);
    
    byte[] inputHash = new SHA1CryptoServiceProvider().ComputeHash(inputBytes);
    
    byte[] privateKeyBytes = Convert.FromBase64String(privateKey
        .Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty)
        .Replace("-----END RSA PRIVATE KEY-----", string.Empty)
        .Replace("\n", string.Empty));
    
    RSACryptoServiceProvider rsa = RSAUtils.DecodeRSAPrivateKey(privateKeyBytes);
    
    byte[] output = rsa.SignHash(inputHash, "SHA1");
    
    Console.WriteLine(Convert.ToBase64String(output));
    
    C#Test

    $input = "<DD><RE>97975000-5</RE><TD>33</TD><F>27</F><FE>2003-09-08</FE><RR>8414240-9</RR><RSR>JORGE GONZALEZ LTDA</RSR><MNT>502946</MNT><IT1>Cajon AFECTO</IT1><CAF version=\"1.0\"><DA><RE>97975000-5</RE><RS>RUT DE PRUEBA</RS><TD>33</TD><RNG><D>1</D><H>200</H></RNG><FA>2003-09-04</FA><RSAPK><M>0a4O6Kbx8Qj3K4iWSP4w7KneZYeJ+g/prihYtIEolKt3cykSxl1zO8vSXu397QhTmsX7SBEudTUx++2zDXBhZw==</M><E>Aw==</E></RSAPK><IDK>100</IDK></DA><FRMA algoritmo=\"SHA1withRSA\">g1AQX0sy8NJugX52k2hTJEZAE9Cuul6pqYBdFxj1N17umW7zG/hAavCALKByHzdYAfZ3LhGTXCai5zNxOo4lDQ==</FRMA></CAF><TSTED>2003-09-08T12:28:31</TSTED></DD>";
    $privateKey = "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBANGuDuim8fEI9yuIlkj+MOyp3mWHifoP6a4oWLSBKJSrd3MpEsZdczvL0l7t/e0IU5rF+0gRLnU1Mfvtsw1wYWcCAQMCQQCLyV9FxKFLW09yWw7bVCCdxpRDr7FRX/EexZB4VhsNxm/vtJfDZyYle0Lfy42LlcsXxPm1w6Q6NnjuW+AeBy67AiEA7iMi5q5xjswqq+49RP55o//jqdZL/pC9rdnUKxsNRMMCIQDhaHdIctErN2hCIP9knS3+9zra4R+5jSXOvI+3xVhWjQIhAJ7CF0R0S7SIHHKe04NUURf/7RvkMqm108k74sdnXi3XAiEAlkWk2vc2HM+a1sCqQxNz/098ketqe7NuidMKeoOQObMCIQCkFAMS9IcPcMjk7zI2r/4EEW63PSXyN7MFAX7TYe25mw==\n-----END RSA PRIVATE KEY-----";
    openssl_sign($input, $output, $privateKey, OPENSSL_ALGO_SHA1);
    echo(base64_encode($output));
    
    string input = "<DD><RE>97975000-5</RE><TD>33</TD><F>27</F><FE>2003-09-08</FE><RR>8414240-9</RR><RSR>JORGE GONZALEZ LTDA</RSR><MNT>502946</MNT><IT1>Cajon AFECTO</IT1><CAF version=\"1.0\"><DA><RE>97975000-5</RE><RS>RUT DE PRUEBA</RS><TD>33</TD><RNG><D>1</D><H>200</H></RNG><FA>2003-09-04</FA><RSAPK><M>0a4O6Kbx8Qj3K4iWSP4w7KneZYeJ+g/prihYtIEolKt3cykSxl1zO8vSXu397QhTmsX7SBEudTUx++2zDXBhZw==</M><E>Aw==</E></RSAPK><IDK>100</IDK></DA><FRMA algoritmo=\"SHA1withRSA\">g1AQX0sy8NJugX52k2hTJEZAE9Cuul6pqYBdFxj1N17umW7zG/hAavCALKByHzdYAfZ3LhGTXCai5zNxOo4lDQ==</FRMA></CAF><TSTED>2003-09-08T12:28:31</TSTED></DD>";
    string privateKey = "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBANGuDuim8fEI9yuIlkj+MOyp3mWHifoP6a4oWLSBKJSrd3MpEsZdczvL0l7t/e0IU5rF+0gRLnU1Mfvtsw1wYWcCAQMCQQCLyV9FxKFLW09yWw7bVCCdxpRDr7FRX/EexZB4VhsNxm/vtJfDZyYle0Lfy42LlcsXxPm1w6Q6NnjuW+AeBy67AiEA7iMi5q5xjswqq+49RP55o//jqdZL/pC9rdnUKxsNRMMCIQDhaHdIctErN2hCIP9knS3+9zra4R+5jSXOvI+3xVhWjQIhAJ7CF0R0S7SIHHKe04NUURf/7RvkMqm108k74sdnXi3XAiEAlkWk2vc2HM+a1sCqQxNz/098ketqe7NuidMKeoOQObMCIQCkFAMS9IcPcMjk7zI2r/4EEW63PSXyN7MFAX7TYe25mw==\n-----END RSA PRIVATE KEY-----";
    
    ASCIIEncoding ByteConverter = new ASCIIEncoding();
    byte[] inputBytes = ByteConverter.GetBytes(input);
    
    byte[] inputHash = new SHA1CryptoServiceProvider().ComputeHash(inputBytes);
    
    byte[] privateKeyBytes = Convert.FromBase64String(privateKey
        .Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty)
        .Replace("-----END RSA PRIVATE KEY-----", string.Empty)
        .Replace("\n", string.Empty));
    
    RSACryptoServiceProvider rsa = RSAUtils.DecodeRSAPrivateKey(privateKeyBytes);
    
    byte[] output = rsa.SignHash(inputHash, "SHA1");
    
    Console.WriteLine(Convert.ToBase64String(output));
    

    这怎么会“太宽”?它并不宽泛。有两个字符串和一个输出字节[]。这并不宽泛。你应该看看这个帖子: