• php openssl_sign 对应 C#版 RSA签名


     

    RSA Key Converter 在线转换工具:https://superdry.apphb.com/tools/online-rsa-key-converter

     

    PHP 代码:

    / rsa 私钥复制到这里

    $private_key = <<<EOD

    PASTE YOUR RSA PRIVATE KEY IN HERE

    EOD;

     // 空着即可,不需要赋值

    $binary_signature = "";

     $algo = "SHA256";

    openssl_sign($data, $binary_signature, $private_key, $algo);

     // 最终生成的 signature

    $signature = base64_encode($binary_signature)

     

    C# 代码实现:

    using System;
    using System.Text;
    using System.Security.Cryptography;
    using System.Web;
    using System.IO;
    using System.Security.Cryptography.X509Certificates;
    
    
    namespace User2MeiCan
    {
       public class RSA
        {
    
            #region RSAWithSHA256
    
            /// <summary>
            /// RSAWithSHA256 签名
            /// </summary>
            /// <param name="data">数据</param>
            /// <returns>密文</returns>
            public static string Sign(string data)
            {
                //转换成适用于.Net的秘钥
                var netKey = "<RSAKeyValue><Modulus>7XdZSrF+spbABFhYuxP7rfJKycvT0O7BmCoSJvU7yHWYqucc8msPDTi8ymdZOPOjHj2BuLUrqGsUm8Ljy8FVM2Bb51GaO2lgiBip9elFkzOJ8XP/ncHHvm4XCq5S201ovJefNC0xOxsXJU4fM+4B6ufYr4WqBmyuxTcZVHweE0k=</Modulus><Exponent>AQAB</Exponent><P>9ryI0kxJL9PupO9NEeWuCUo4xcl9x/M9+mtkfY3VoDDDV1E/eUjmoTfANYwrjcddiQrO0MLyEdootiLpN77qOw==</P><Q>9mG2//6moxVOsvFadUotnhlVM8+AlBCQV2FbBiXPugrMHdVtBG3+MsVdTII3Z4I/uuCWtedrPsBgF+0XRqMcSw==</Q><DP>wzX5HkFC6jdIKXA3TsCkSC9T6ZB4FplpYNZUxE1SRhIuisf6ay/1YHomdXc4Ak1IwKMva9XBBcTPzwKh9/vxfw==</DP><DQ>zsTCp6Q2hLblDRewKq7OCdiIwKpr5dbgy/RQR6CD7EYTdxYeH5GPu1wXKJY/mQaeJV9GG/LS9h7MhkfbONS6cQ==</DQ><InverseQ>dBEb5vloBDLcSQFDQO/VZ9SKFHCmHLXluhhIizYKGzgf3OXEGNDSAC3qy+ZTnLd3N5iYrVbK52UoiLOLhhNMqA==</InverseQ><D>iBOTTHUn6EjwoczKk/GgkI4+gyLVL24R7BN3sXFoH7gbkxu6/8OPrYDs1oOgoj0jJSoT0vemm+04swVcKh+QpTSniPswQl1n4KNW+B7G2RZrzSeP9RmIzWg4vpgfAfhm0+1j6kUJMrWt2ff7TvSoEH22dWe1s3+OrQt3t/S3tQ0=</D></RSAKeyValue>"; //RSAPrivateKeyJava2DotNet(privateKey);
                var rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(netKey);
                //创建一个空对象
                var rsaClear = new RSACryptoServiceProvider();
                var paras = rsa.ExportParameters(true);
                rsaClear.ImportParameters(paras);
                //签名返回
                using (var sha256 = new SHA256CryptoServiceProvider())
                {
                    var signData = rsa.SignData(Encoding.UTF8.GetBytes(data), sha256);
                    return Convert.ToBase64String(signData);
                }
            }
    
            #endregion
    
    
            #region RSAWithSHA256
            /// <summary>
            /// RSAWithSHA256 签名
            /// </summary>
            /// <param name="data">数据</param>
            /// <param name="privateKeyPath">私钥文件路径</param>
            /// <returns>密文</returns>
            public static string Sign(string data, string privateKeyPath)
            {
                // using (RSACryptoServiceProvider rsa = opensslkey.DecodePrivateKeyInfo(merchantPrivateKey))
                RSACryptoServiceProvider rsaCsp = LoadCertificateFile(privateKeyPath);
                byte[] dataBytes = Encoding.Default.GetBytes(data);
                byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA256");
                return Convert.ToBase64String(signatureBytes);
            }
    
            /// <summary>
            /// RSAWithSHA256 签名
            /// </summary>
            /// <param name="data">数据</param>
            /// <param name="privateKey">私钥字符串(参数privateKey是Pem私钥文件中去除头(-----BEGIN RSA PRIVATE KEY-----)和尾(-----END RSA PRIVATE KEY-----)以及换行符后的字符串)</param>
            /// <returns>密文</returns>
            public static string SignByKey(string data, string privateKey)
            {
                using (RSACryptoServiceProvider rsaCsp = DecodeRSAPrivateKey(Convert.FromBase64String(privateKey)))
                {
                    byte[] dataBytes = Encoding.Default.GetBytes(data);
                    byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA256");
                    return Convert.ToBase64String(signatureBytes);
                }
            }
    
            private static byte[] GetPem(string type, byte[] data)
            {
    
                string pem = Encoding.UTF8.GetString(data);
                string header = String.Format("-----BEGIN {0}-----\n", type);
                string footer = String.Format("-----END {0}-----", type);
                int start = pem.IndexOf(header) + header.Length;
                int end = pem.IndexOf(footer, start);
                string base64 = pem.Substring(start, (end - start));
                return Convert.FromBase64String(base64);
            }
            private static RSACryptoServiceProvider LoadCertificateFile(string filename)
            {
                using (FileStream fs = File.OpenRead(filename))
                {
                    byte[] data = new byte[fs.Length];
                    byte[] res = null;
                    fs.Read(data, 0, data.Length);
                    if (data[0] != 0x30)
                    {
                        res = GetPem("RSA PRIVATE KEY", data);
                    }
                    try
                    {
                        RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res);
    
                        return rsa;
                    }
                    catch (Exception ex)
                    {
                    }
                    return null;
                }
            }
    
            private 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;
            }
    
    
            #endregion
        }
    }
    View Code
  • 相关阅读:
    完美图解教程 Linux环境VNC服务安装、配置与使用
    c语言中<stdbool.h>的使用
    UNIX文件结构(转自UNIX/AIX操作系统基础教程)
    umask
    在AIX环境为Oracle表空间增加裸设备(逻辑卷)
    面的面积大小合线的长度的判断。
    不用新浪博客了。以后的日常感悟也在这里写了, 新浪太烂了。 (感叹也没用,什么都写不出来。 )
    轴心工具的做法。
    选择因素随机的判断。
    上面发的那个完整版变量还有问题,难道我不是用英文输入法, 电脑不说谎 ,看来我是大意了。下面是最终版。
  • 原文地址:https://www.cnblogs.com/Xingsoft-555/p/15014961.html
Copyright © 2020-2023  润新知