C# RSA 验证签名 (源码)

来源:互联网 发布:为什么安装不了知乎 编辑:程序博客网 时间:2024/06/07 15:41
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Security.Cryptography;using System.Text;using System.Threading.Tasks;//已测试过,以下代码为网络资源的整理namespace ConsoleApplication3{    class Program    {        const string data = @"改为实际数据";        const string sign = @"改为签名";        //不包含“-----BEGIN PUBLIC KEY-----”        const string publicKey = @"改为公钥";        static void Main(string[] args)        {            bool result= VerifyHash(publicKey,data,sign);            if (result == true)            {                Console.WriteLine("验证签名成功");            }            else            {                Console.WriteLine("失败");            }        }        public static bool VerifyHash(string publicKey, string data, string sign)        {            byte[] signedData = Encoding.UTF8.GetBytes(data);            byte[] signature = Convert.FromBase64String(sign);            RSACryptoServiceProvider rsaCSP = CreateRsaProviderFromPublicKey(publicKey);            SHA1Managed hash = new SHA1Managed();            byte[] hashedData;            rsaCSP.VerifyData(signedData, "SHA1", signature);            hashedData = hash.ComputeHash(signedData);            return rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA1"), signature);        }        public static bool CompareBytearrays(byte[] a, byte[] b)        {            if (a.Length != b.Length)                return false;            int i = 0;            foreach (byte c in a)            {                if (c != b[i])                    return false;                i++;            }            return true;        }        static  RSACryptoServiceProvider CreateRsaProviderFromPublicKey(string publicKeyString)        {            // encoded OID sequence for  PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"            byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };            byte[] x509key;            byte[] seq = new byte[15];            int x509size;            x509key = Convert.FromBase64String(publicKeyString);            x509size = x509key.Length;            // ---------  Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob  ------            using (MemoryStream mem = new MemoryStream(x509key))            {                using (BinaryReader binr = new BinaryReader(mem))  //wrap Memory Stream with BinaryReader for easy reading                {                    byte bt = 0;                    ushort twobytes = 0;                    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;                    seq = binr.ReadBytes(15);       //read the Sequence OID                    if (!CompareBytearrays(seq, SeqOID))    //make sure Sequence for OID is correct                        return null;                    twobytes = binr.ReadUInt16();                    if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)                        binr.ReadByte();    //advance 1 byte                    else if (twobytes == 0x8203)                        binr.ReadInt16();   //advance 2 bytes                    else                        return null;                    bt = binr.ReadByte();                    if (bt != 0x00)     //expect null byte next                        return null;                    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();                    byte lowbyte = 0x00;                    byte highbyte = 0x00;                    if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)                        lowbyte = binr.ReadByte();  // read next bytes which is bytes in modulus                    else if (twobytes == 0x8202)                    {                        highbyte = binr.ReadByte(); //advance 2 bytes                        lowbyte = binr.ReadByte();                    }                    else                        return null;                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };   //reverse byte order since asn.1 key uses big endian order                    int modsize = BitConverter.ToInt32(modint, 0);                    int firstbyte = binr.PeekChar();                    if (firstbyte == 0x00)                    {   //if first byte (highest order) of modulus is zero, don't include it                        binr.ReadByte();    //skip this null byte                        modsize -= 1;   //reduce modulus buffer size by 1                    }                    byte[] modulus = binr.ReadBytes(modsize);   //read the modulus bytes                    if (binr.ReadByte() != 0x02)            //expect an Integer for the exponent data                        return null;                    int expbytes = (int)binr.ReadByte();        // should only need one byte for actual exponent data (for all useful values)                    byte[] exponent = binr.ReadBytes(expbytes);                    // ------- create RSACryptoServiceProvider instance and initialize with public key -----                    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();                    RSAParameters RSAKeyInfo = new RSAParameters();                    RSAKeyInfo.Modulus = modulus;                    RSAKeyInfo.Exponent = exponent;                    RSA.ImportParameters(RSAKeyInfo);                    return RSA;                }            }        }    }}


                                             
0 0
原创粉丝点击