.net 实现签名验签
本人被要求实现.net的签名验签,还是个.net菜鸡,来分享下采坑过程
依然,签名验签使用的证书格式依然是pem,有关使用openssl将.p12和der转pem的命令请转到php实现签名验签
.net不像php只要将pem文件读出来就可以签名验签,需要解析pem文件的主体内容,获取参数装载特定类,具体看一下代码:
//有些函数我也不知道是干嘛的,反正.net的实现要这样,采百家之长,签的了名,验的了签就对了
//自己去单元测试下
//pem文件是我使用的是绝对路径
public class Signature- {
- //签名,返回256位字节数组
- public static byte[] Sign(string content,string path,string code)
- {
- RSACryptoServiceProvider rsaCsp = RSAProviderPrivate(path);
- byte[] dataBytes = Encoding.UTF8.GetBytes(content);
- byte[] signatureBytes = rsaCsp.SignData(dataBytes, code);
- return signatureBytes;
- }
- //验签
- public static Boolean Verify(string content, byte[] signContent, string path, string code)
- {
- byte[] dataBytes = Encoding.UTF8.GetBytes(content);
- byte[] publicPemBytes = LoadCertificateFile(path, "PUBLIC KEY");
- RSACryptoServiceProvider rsaPub = CreateRsaProviderFromPublicKey(publicPemBytes);
- Boolean flag= rsaPub.VerifyData(dataBytes,code, signContent);
- return flag;
- }
- //加载公私钥证书文件
- private static byte[] LoadCertificateFile(String filePath,string type)
- {
- using (System.IO.FileStream fs = System.IO.File.OpenRead(filePath))
- {
- byte[] data = new byte[fs.Length];
- byte[] res = null;
- fs.Read(data, 0, data.Length);
- if (data[0] != 0x30)
- {
- res = GetPem(type, data);
- }
- return res;
- }
- }
- private static RSACryptoServiceProvider RSAProviderPrivate(String filePath)
- {
- byte[] res = LoadCertificateFile(filePath, "RSA PRIVATE KEY");
- try
- {
- RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res);
- return rsa;
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
- return null;
- }
- //获取pem文件的主体内容,并转换成字节数组
- 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 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;
- }
- 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 e)
- {
- Console.WriteLine(e);
- 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;
- }
- private static RSAParameters ConvertFromPublicKey(byte[] publicPemBytes)
- {
- byte[] keyData = publicPemBytes;
- if (keyData.Length < 162)
- {
- throw new ArgumentException("pem file content is incorrect.");
- }
- byte[] pemModulus = new byte[128];
- byte[] pemPublicExponent = new byte[3];
- Array.Copy(keyData, 29, pemModulus, 0, 128);
- Array.Copy(keyData, 159, pemPublicExponent, 0, 3);
- RSAParameters para = new RSAParameters();
- para.Modulus = pemModulus;
- para.Exponent = pemPublicExponent;
- return para;
- }
- public static RSACryptoServiceProvider CreateRsaProviderFromPublicKey(byte[] publicKeyBytes)
- {
- 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 = publicKeyBytes;
- x509size = x509key.Length;
- using (MemoryStream mem = new MemoryStream(x509key))
- {
- using (BinaryReader 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 = (int)binr.ReadByte();
- byte[] exponent = binr.ReadBytes(expbytes);
- RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
- RSAParameters RSAKeyInfo = new RSAParameters();
- RSAKeyInfo.Modulus = modulus;
- RSAKeyInfo.Exponent = exponent;
- RSA.ImportParameters(RSAKeyInfo);
- return RSA;
- }
- }
- }
- }
.net 实现签名验签的更多相关文章
- RSA签名验签
import android.util.Base64; import java.security.KeyFactory; import java.security.PrivateKey; import ...
- 利用SHA-1算法和RSA秘钥进行签名验签(带注释)
背景介绍 1.SHA 安全散列算法SHA (Secure Hash Algorithm)是美国国家标准和技术局发布的国家标准FIPS PUB 180-1,一般称为SHA-1.其对长度不超过264二进制 ...
- RSA密钥生成、加密解密、签名验签
RSA 非对称加密公钥加密,私钥解密 私钥签名,公钥验签 下面是生成随机密钥对: //随机生成密钥对 KeyPairGenerator keyPairGen = null; try { keyPair ...
- C# RSACryptoServiceProvider加密解密签名验签和DESCryptoServic
C#在using System.Security.Cryptography下有 DESCryptoServiceProvider RSACryptoServiceProvider DESCryptoS ...
- RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密
原文:RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密 C#在using System.Security.Cryptograph ...
- 数据安全管理:RSA加密算法,签名验签流程详解
本文源码:GitHub·点这里 || GitEE·点这里 一.RSA算法简介 1.加密解密 RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用.可以在不直接传递密钥的情况下,完成加 ...
- js rsa sign使用笔记(加密,解密,签名,验签)
你将会收获: js如何加密, 解密 js如何签名, 验签 js和Java交互如何相互解密, 验签(重点) 通过谷歌, 发现jsrsasign库使用者较多. 查看api发现这个库功能很健全. 本文使用方 ...
- [Python3] RSA的加解密和签名/验签实现 -- 使用pycrytodome
Crypto 包介绍: pycrypto,pycrytodome 和 crypto 是一个东西,crypto 在 python 上面的名字是 pycrypto 它是一个第三方库,但是已经停止更新,所以 ...
- php 实现签名验签
本人php菜鸟,主要使用php实现简单的签名验签功能 以下php代码使用的密钥格式为pem格式,其他证书格式可以使用openssl进行转换(未安装请实现安装): 以下是.p12文件导出pem格式公私钥 ...
随机推荐
- Python下的图像处理库,你选哪个?
奥里给~ 转载:https://blog.csdn.net/chen801090/article/details/105795068/ 在进行数字图像处理时,我们经常需要对图像进行读取.保存.缩放.裁 ...
- [学习笔记] Tarjan算法求桥和割点
在之前的博客中我们已经介绍了如何用Tarjan算法求有向图中的强连通分量,而今天我们要谈的Tarjan求桥.割点,也是和上篇有博客有类似之处的. 关于桥和割点: 桥:在一个有向图中,如果删去一条边,而 ...
- 超详细的TCP、Sokcket和SuperSocket与TCP入门指导
前言 本文主要介绍TCP.Sokcket和SuperSocket的基础使用. 创建实例模式的SuperSocket服务 首先创建控制台项目,然后Nuget添加引用SuperSocket.Engine. ...
- 扩展、接管MVC都不会,还会用Spring Boot?
持续原创输出,点击上方蓝字关注我 目录 前言 Spring Boot 版本 如何扩展MVC? 如何自定义一个拦截器? 什么都不配置为什么依然能运行MVC相关的功能? 如何全面接管MVC?[不推荐] 为 ...
- 你想了解的《javaScript语言精粹》(三)
# javaScript语言精粹 # 第三章 对象 - javaScript 数据类型 1. 基础数据类型 Number String Boolean Undefined N ...
- 多测师讲解 ———python2和Python3区别
python3.x和python2.x的区别:1.Python3.X源码文件默认使用utf-8编码,而python2.x的编译最前端需要加上#coding=utf-82.python3.x里打印pri ...
- JVM 第六篇:极致优化 IDEA 启动速度
本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 引言 相信做 Java 开发的同学,对 IDEA 这个工具应该都不陌生,即使不使用 IDEA 做开发,那么对 Eclipse 这个工具应该 ...
- MeteoInfoLab脚本示例:FY-3C全球火点HDF数据
FY-3C全球火点HDF数据包含一个FIRES二维变量,第一维是火点数,第二维是一些属性,其中第3.4列分别是火点的纬度和经度.下面的脚本示例读出所有火点经纬度并绘图.脚本程序: #Add data ...
- 【UER #1】DZY Loves Graph
UOJ小清新题表 题目内容 UOJ链接 DZY开始有\(n\)个点,现在他对这\(n\)个点进行了\(m\)次操作,对于第\(i\)个操作(从\(1\)开始编号)有可能的三种情况: Add a b: ...
- Spring Aop 详解一
Aop 是一个编程思想,最初是一个理论,最后落地成了很多的技术实现. 我们写一个系统,都希望尽量少写点儿重复的东西.而很多时候呢,又不得不写一些重复的东西.比如访问某些方法的权限,执行某些方法性能的日 ...