zoukankan      html  css  js  c++  java
  • openssl使用以及C#加密和数字签名


    如何使用openssl生成RSA公钥和私钥对

    http://blog.csdn.net/scape1989/article/details/18959657

    https://www.openssl.org/docs/manmaster/apps/rsautl.html


    C# RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密

    http://www.2cto.com/kf/201007/52626.html

    RSA Key Converter(XML to PEM,PEM to XML)
    https://superdry.apphb.com/tools/online-rsa-key-converter

    openssl
    it defaulte generate RSA format , sometimes need convert to pkcs8 format
    
    generate a private key pair with pkcs8 format
    openssl>pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt
    
    generate a private key pair with pem format
    openssl>genrsa -out rsa_private_key.pem 1024
    
    output the public key 
    
    openssl>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
    
    use public key to encrypt data
    openssl>rsautl -encrypt -in orig.txt -inkey rsa_public_key.pem -pubin -out orig.en 
    
    use private key to decrypt data 
    openssl>rsautl -decrypt -in orig.en -inkey rsa_private_key.pem -out orig.de
    
    use private key to signature data 
    rsautl  -sign -in orig.txt -inkey rsa_private_key.pem -out sig
    
    output the data with private key from signed data
    rsautl -verify -in sig -inkey rsa_private_key.pem
    
    !!!Error:output the data with public key from signed data
    rsautl -verify -in sig -inkey rsa_public_key.pem
    
    Examine the reaw signed data
    rsautl -verify -in sig -inkey rsa_private_key.pem -raw -hexdump
    


    SSOBLL sso = newSSOBLL();

    string signature = sso.SignData(string.Empty,SSOBLL.KeyType.PrivatePEM, sigData);

    string signature2 = sso.SignData(string.Empty,SSOBLL.KeyType.PrivateXML, sigData);

    bool valid = sso.VerifySignData(string.Empty,SSOBLL.KeyType.PublicXML,sigData,Convert.FromBase64String(signature));



    public class SSOBLL
        {
            public enum KeyType
            {
                PrivatePEM,
                PublicPEM,
                PrivateXML,
                PublicXML
            }
    
            public string SignData(string privateKeyStr, KeyType keyType, string dataStr)
            {
                byte[] data = Encoding.UTF8.GetBytes(dataStr);
                string base64 = string.Empty;
                if (keyType == KeyType.PrivatePEM)
                {
                    
                    string keyStr = GetKey(privateKeyStr, KeyType.PrivatePEM);
                    byte[] privateKey = Helpers.GetBytesFromPEM(keyStr, PemStringType.RsaPrivateKey);
                    RSACryptoServiceProvider rsa = Crypto.DecodeRsaPrivateKey(privateKey);
                    byte[] hash = rsa.SignData(data, SHA1.Create());
                    base64 = Convert.ToBase64String(hash);
                }
                if (keyType == KeyType.PrivateXML)
                {
                    string privatekey = GetKey(privateKeyStr, keyType);
                    RSACryptoServiceProvider oRSA3 = new RSACryptoServiceProvider();
                    oRSA3.FromXmlString(privatekey);
                    byte[] BOutput = oRSA3.SignData(data, "SHA1");
                    base64 = Convert.ToBase64String(BOutput);
                }
                return base64;
            }
    
            public bool VerifySignData(RSACryptoServiceProvider rsa, KeyType keyType, string dataStr, byte[] dataHash)
            {
                byte[] data = Encoding.UTF8.GetBytes(dataStr);
                bool valid = false;
                if (keyType == KeyType.PublicPEM)
                {
                    RSAParameters key = rsa.ExportParameters(false); // false:公钥  true:私钥
                    RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
                    RSAalg.ImportParameters(key);
                    valid = RSAalg.VerifyData(data, new SHA1CryptoServiceProvider(), dataHash);
                }
                else if (keyType == KeyType.PublicXML)
                {
                    string publickey = rsa.ToXmlString(false);//false:公钥  true:私钥
                    valid = VerifySignData(publickey, keyType, dataStr, dataHash);
                }
                return valid;
            }
    
            public bool VerifySignData(string keyStr, KeyType keyType, string dataStr, byte[] dataHash)
            {
                byte[] data = Encoding.UTF8.GetBytes(dataStr);
                bool valid = false;
                if (keyType == KeyType.PublicXML)
                {
                    RSACryptoServiceProvider oRSA4 = new RSACryptoServiceProvider();
                    string publickey = GetKey(keyStr, KeyType.PublicXML);
                    oRSA4.FromXmlString(publickey);
                    valid = oRSA4.VerifyData(data, "SHA1", dataHash);
                }
                return valid;
            }
    
            private string GetKey(string keyStr, KeyType keyType)
            {
                string key = keyStr;
                if (string.IsNullOrWhiteSpace(keyStr))
                {
                    string KeyFile = AppDomain.CurrentDomain.BaseDirectory;
                    switch (keyType)
                    {
                        case KeyType.PrivatePEM:
                            KeyFile += @"Keysprivate.pem";
                            break;
                        case KeyType.PublicPEM:
                            KeyFile += @"Keyspublic.pem";
                            break;
                        case KeyType.PrivateXML:
                            KeyFile += @"Keysprivate.xml";
                            break;
                        case KeyType.PublicXML:
                            KeyFile += @"Keyspublic.xml";
                            break;
                        default:
                            KeyFile += @"Keysprivate.pem";
                            break;
                    }
                    key = File.ReadAllText(KeyFile);
                }
                return key;
            }
    
         
        }



       public class Crypto
        {
            /// <summary>
            /// This helper function parses an RSA private key using the ASN.1 format
            /// </summary>
            /// <param name="privateKeyBytes">Byte array containing PEM string of private key.</param>
            /// <returns>An instance of <see cref="RSACryptoServiceProvider"/> rapresenting the requested private key.
            /// Null if method fails on retriving the key.</returns>
            public static RSACryptoServiceProvider DecodeRsaPrivateKey(byte[] privateKeyBytes)
            {
                MemoryStream ms = new MemoryStream(privateKeyBytes);
                BinaryReader rd = new BinaryReader(ms);
    
                try
                {
                    byte byteValue;
                    ushort shortValue;
    
                    shortValue = rd.ReadUInt16();
    
                    switch (shortValue)
                    {
                        case 0x8130:
                            // If true, data is little endian since the proper logical seq is 0x30 0x81
                            rd.ReadByte(); //advance 1 byte
                            break;
                        case 0x8230:
                            rd.ReadInt16();  //advance 2 bytes
                            break;
                        default:
                            Debug.Assert(false);     // Improper ASN.1 format
                            return null;
                    }
    
                    shortValue = rd.ReadUInt16();
                    if (shortValue != 0x0102) // (version number)
                    {
                        Debug.Assert(false);     // Improper ASN.1 format, unexpected version number
                        return null;
                    }
    
                    byteValue = rd.ReadByte();
                    if (byteValue != 0x00)
                    {
                        Debug.Assert(false);     // Improper ASN.1 format
                        return null;
                    }
    
                    // The data following the version will be the ASN.1 data itself, which in our case
                    // are a sequence of integers.
    
                    // In order to solve a problem with instancing RSACryptoServiceProvider
                    // via default constructor on .net 4.0 this is a hack
                    CspParameters parms = new CspParameters();
                    parms.Flags = CspProviderFlags.NoFlags;
                    parms.KeyContainerName = Guid.NewGuid().ToString().ToUpperInvariant();
                    parms.ProviderType = ((Environment.OSVersion.Version.Major > 5) || ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1))) ? 0x18 : 1;
    
                    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(parms);
                    RSAParameters rsAparams = new RSAParameters();
    
                    rsAparams.Modulus = rd.ReadBytes(Helpers.DecodeIntegerSize(rd));
    
                    // Argh, this is a pain.  From emperical testing it appears to be that RSAParameters doesn't like byte buffers that
                    // have their leading zeros removed.  The RFC doesn't address this area that I can see, so it's hard to say that this
                    // is a bug, but it sure would be helpful if it allowed that. So, there's some extra code here that knows what the
                    // sizes of the various components are supposed to be.  Using these sizes we can ensure the buffer sizes are exactly
                    // what the RSAParameters expect.  Thanks, Microsoft.
                    RSAParameterTraits traits = new RSAParameterTraits(rsAparams.Modulus.Length * 8);
    
                    rsAparams.Modulus = Helpers.AlignBytes(rsAparams.Modulus, traits.size_Mod);
                    rsAparams.Exponent = Helpers.AlignBytes(rd.ReadBytes(Helpers.DecodeIntegerSize(rd)), traits.size_Exp);
                    rsAparams.D = Helpers.AlignBytes(rd.ReadBytes(Helpers.DecodeIntegerSize(rd)), traits.size_D);
                    rsAparams.P = Helpers.AlignBytes(rd.ReadBytes(Helpers.DecodeIntegerSize(rd)), traits.size_P);
                    rsAparams.Q = Helpers.AlignBytes(rd.ReadBytes(Helpers.DecodeIntegerSize(rd)), traits.size_Q);
                    rsAparams.DP = Helpers.AlignBytes(rd.ReadBytes(Helpers.DecodeIntegerSize(rd)), traits.size_DP);
                    rsAparams.DQ = Helpers.AlignBytes(rd.ReadBytes(Helpers.DecodeIntegerSize(rd)), traits.size_DQ);
                    rsAparams.InverseQ = Helpers.AlignBytes(rd.ReadBytes(Helpers.DecodeIntegerSize(rd)), traits.size_InvQ);
    
                    rsa.ImportParameters(rsAparams);
                    return rsa;
                }
                catch (Exception)
                {
                    Debug.Assert(false);
                    return null;
                }
                finally
                {
                    rd.Close();
                }
            }
        }

       public enum PemStringType
        {
            Certificate,
            RsaPrivateKey,
            RsaPublicKey
        }
    
        public class Helpers
        {
            /// <summary>
            /// This helper function parses an integer size from the reader using the ASN.1 format
            /// </summary>
            /// <param name="rd"></param>
            /// <returns></returns>
            public static int DecodeIntegerSize(System.IO.BinaryReader rd)
            {
                byte byteValue;
                int count;
    
                byteValue = rd.ReadByte();
                if (byteValue != 0x02)        // indicates an ASN.1 integer value follows
                    return 0;
    
                byteValue = rd.ReadByte();
                if (byteValue == 0x81)
                {
                    count = rd.ReadByte();    // data size is the following byte
                }
                else if (byteValue == 0x82)
                {
                    byte hi = rd.ReadByte();  // data size in next 2 bytes
                    byte lo = rd.ReadByte();
                    count = BitConverter.ToUInt16(new[] { lo, hi }, 0);
                }
                else
                {
                    count = byteValue;        // we already have the data size
                }
    
                //remove high order zeros in data
                while (rd.ReadByte() == 0x00)
                {
                    count -= 1;
                }
                rd.BaseStream.Seek(-1, System.IO.SeekOrigin.Current);
    
                return count;
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="pemString"></param>
            /// <param name="type"></param>
            /// <returns></returns>
            public static byte[] GetBytesFromPEM(string pemString, PemStringType type)
            {
                string header; string footer;
    
                switch (type)
                {
                    case PemStringType.Certificate:
                        header = "-----BEGIN CERTIFICATE-----";
                        footer = "-----END CERTIFICATE-----";
                        break;
                    case PemStringType.RsaPrivateKey:
                        header = "-----BEGIN RSA PRIVATE KEY-----";
                        footer = "-----END RSA PRIVATE KEY-----";
                        break;
                    case PemStringType.RsaPublicKey:
                        header = "-----BEGIN PUBLIC KEY-----";
                        footer = "-----END PUBLIC KEY-----";
                        break;
                    default:
                        return null;
                }
    
                int start = pemString.IndexOf(header) + header.Length;
                int end = pemString.IndexOf(footer, start) - start;
                return Convert.FromBase64String(pemString.Substring(start, end));
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="inputBytes"></param>
            /// <param name="alignSize"></param>
            /// <returns></returns>
            public static byte[] AlignBytes(byte[] inputBytes, int alignSize)
            {
                int    inputBytesSize = inputBytes.Length;
    
                if ((alignSize != -1) && (inputBytesSize < alignSize))
                {
                    byte[] buf = new byte[alignSize];
                    for (int i = 0; i < inputBytesSize; ++i)
                    {
                        buf[i + (alignSize - inputBytesSize)] = inputBytes[i];
                    }
                    return buf;
                }
                else
                {
                    return inputBytes;      // Already aligned, or doesn't need alignment
                }
            }

       internal class RSAParameterTraits
        {
            public RSAParameterTraits(int modulusLengthInBits)
            {
                // The modulus length is supposed to be one of the common lengths, which is the commonly referred to strength of the key,
                // like 1024 bit, 2048 bit, etc.  It might be a few bits off though, since if the modulus has leading zeros it could show
                // up as 1016 bits or something like that.
                int assumedLength = -1;
                double logbase = Math.Log(modulusLengthInBits, 2);
                if (logbase == (int)logbase)
                {
                    // It's already an even power of 2
                    assumedLength = modulusLengthInBits;
                }
                else
                {
                    // It's not an even power of 2, so round it up to the nearest power of 2.
                    assumedLength = (int)(logbase + 1.0);
                    assumedLength = (int)(Math.Pow(2, assumedLength));
                    System.Diagnostics.Debug.Assert(false);  // Can this really happen in the field?  I've never seen it, so if it happens
                    // you should verify that this really does the 'right' thing!
                }
    
                switch (assumedLength)
                {
                    case 1024:
                        this.size_Mod = 0x80;
                        this.size_Exp = -1;
                        this.size_D = 0x80;
                        this.size_P = 0x40;
                        this.size_Q = 0x40;
                        this.size_DP = 0x40;
                        this.size_DQ = 0x40;
                        this.size_InvQ = 0x40;
                        break;
                    case 2048:
                        this.size_Mod = 0x100;
                        this.size_Exp = -1;
                        this.size_D = 0x100;
                        this.size_P = 0x80;
                        this.size_Q = 0x80;
                        this.size_DP = 0x80;
                        this.size_DQ = 0x80;
                        this.size_InvQ = 0x80;
                        break;
                    case 4096:
                        this.size_Mod = 0x200;
                        this.size_Exp = -1;
                        this.size_D = 0x200;
                        this.size_P = 0x100;
                        this.size_Q = 0x100;
                        this.size_DP = 0x100;
                        this.size_DQ = 0x100;
                        this.size_InvQ = 0x100;
                        break;
                    default:
                        System.Diagnostics.Debug.Assert(false); // Unknown key size?
                        break;
                }
            }
    
            public int size_Mod  = -1;
            public int size_Exp  = -1;
            public int size_D    = -1;
            public int size_P    = -1;
            public int size_Q    = -1;
            public int size_DP   = -1;
            public int size_DQ   = -1;
            public int size_InvQ = -1;
        }

    
    
    
  • 相关阅读:
    关于机器学习系统的方向
    图像去雾
    中国九十年代摇滚
    matlab 将数字矩阵转换成图像
    vue-router路由守卫ie浏览器下报错问题解决
    vue:index.html、main.js、app.vue
    vue关于for循环
    element-ui表单校验
    记录vue组件引入components两次的后果
    vue组件通信
  • 原文地址:https://www.cnblogs.com/sui84/p/6777024.html
Copyright © 2011-2022 走看看