/// <summary> /// 使用 RSA 公钥验证签名 /// </summary> public static bool RsaVerifySign(string message, string signature, string publicKey, string charset = "utf-8", RsaFormat signType = RsaFormat.SHA1) { try { var sPublicKeyPem = publicKey; var rsa = CreateRsaProviderFromPublicKey(sPublicKeyPem, signType); var hashName = signType == RsaFormat.SHA1 ? HashAlgorithmName.SHA1 : HashAlgorithmName.SHA256; var data = Encoding.GetEncoding(charset).GetBytes(message); return(rsa.VerifyData(data, Convert.FromBase64String(signature), hashName, RSASignaturePadding.Pkcs1)); } catch { return(false); } }
/// <summary> 使用 RSA 私钥签名 </summary> public static string RsaSignature(string message, string privateKey, string charset = "utf-8", RsaFormat signType = RsaFormat.SHA1) { byte[] signatureBytes = null; try { var data = Convert.FromBase64String(privateKey); var rsa = DecodeRsaPrivateKey(data, signType); using (rsa) { var messageBytes = Encoding.GetEncoding(charset).GetBytes(message); var hashName = signType == RsaFormat.SHA1 ? HashAlgorithmName.SHA1 : HashAlgorithmName.SHA256; signatureBytes = rsa.SignData(messageBytes, hashName, RSASignaturePadding.Pkcs1); } } catch (Exception) { throw new Exception($"您使用的私钥格式错误,请检查RSA私钥配置,charset = {charset}"); } return(Convert.ToBase64String(signatureBytes)); }
private static RSA DecodeRsaPrivateKey(byte[] privkey, RsaFormat signType) { byte[] MODULUS, E, D, P, Q, DP, DQ, IQ; var mem = new MemoryStream(privkey); var binr = new BinaryReader(mem); byte bt = 0; ushort twobytes = 0; int elems = 0; try { twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) { binr.ReadByte(); } else if (twobytes == 0x8230) { binr.ReadInt16(); } else { return(null); } twobytes = binr.ReadUInt16(); if (twobytes != 0x0102) { return(null); } bt = binr.ReadByte(); if (bt != 0x00) { return(null); } 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); var bitLen = 1024; if (signType == RsaFormat.SHA256) { bitLen = 2048; } var rsa = RSA.Create(); rsa.KeySize = bitLen; 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) { return(null); } finally { binr.Close(); mem.Dispose(); } }
private static RSA CreateRsaProviderFromPublicKey(string publicKeyString, RsaFormat signType) { byte[] seqOid = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 }; byte[] seq = new byte[15]; var x509Key = Convert.FromBase64String(publicKeyString); using (var mem = new MemoryStream(x509Key)) { using (var binr = new BinaryReader(mem)) { byte bt = 0; ushort twobytes = 0; twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) { binr.ReadByte(); } else if (twobytes == 0x8230) { binr.ReadInt16(); } else { return(null); } seq = binr.ReadBytes(15); if (!CompareBytearrays(seq, seqOid)) { return(null); } twobytes = binr.ReadUInt16(); if (twobytes == 0x8103) { binr.ReadByte(); } else if (twobytes == 0x8203) { binr.ReadInt16(); } else { return(null); } bt = binr.ReadByte(); if (bt != 0x00) { return(null); } twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) { binr.ReadByte(); } else if (twobytes == 0x8230) { binr.ReadInt16(); } else { return(null); } twobytes = binr.ReadUInt16(); byte lowbyte = 0x00; byte highbyte = 0x00; if (twobytes == 0x8102) { lowbyte = binr.ReadByte(); } else if (twobytes == 0x8202) { highbyte = binr.ReadByte(); lowbyte = binr.ReadByte(); } else { return(null); } byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; int modsize = BitConverter.ToInt32(modint, 0); int firstbyte = binr.PeekChar(); if (firstbyte == 0x00) { binr.ReadByte(); modsize -= 1; } byte[] modulus = binr.ReadBytes(modsize); if (binr.ReadByte() != 0x02) { return(null); } int expbytes = binr.ReadByte(); byte[] exponent = binr.ReadBytes(expbytes); var rsa = RSA.Create(); rsa.KeySize = signType == RsaFormat.SHA1 ? 1024 : 2048; var rsaKeyInfo = new RSAParameters { Modulus = modulus, Exponent = exponent }; rsa.ImportParameters(rsaKeyInfo); return(rsa); } } }