数字签名是一种用于验证数字文档的技术,它可以确保文档的完整性和来源。本文将介绍数字签名的概念和原理,以及如何使用.Net Core创建和验证数字签名。
什么数字签名?数字签名的原理是使用非对称加密算法,即公钥和私钥。公钥是公开的,任何人都可以用它来验证签名,而私钥是保密的,只有签名者才能用它来创建签名。数字签名的过程如下:
签名者使用私钥对文档的哈希值进行加密,得到数字签名。
签名者将文档和数字签名一起发送给接收者。
接收者使用公钥对数字签名进行解密,得到文档的哈希值。
接收者使用相同的哈希算法对文档进行哈希,得到文档的哈希值。
接收者比较两个哈希值,如果相同,说明文档没有被篡改,且来源可信。
点个关注吧????
.Net Core中如何使用数字签名
.Net Core提供了一些类和方法来生成密钥、签名和验证,使用很方便。我们以一个简单的示例来说明,假设有这样一个文档,内容如下:
Hello, this is a document that needs to be signed.
我们目的是使用数字签名来保护这个文档的完整性和来源。以下是具体的步骤:
一、创建密钥
创建数字签名的第一步是获取公钥和私钥,我们可以有两种方式来获取密钥,一种是以编程方式生成密钥,另一种是通过外部工具创建导入。
1、以编程方式生成密钥
首先,我们需要创建一个RSA
对象,用于生成公钥和私钥。可以使用RSA.Create
方法来创建一个RSA
对象,也可以使用RSACryptoServiceProvider
类的构造函数来创建一个RSACryptoServiceProvider
对象,它是RSA
类的一个子类。例如:
// 使用RSA.Create方法创建一个RSA对象
RSA rsa = RSA.Create;
// 使用RSACryptoServiceProvider类的构造函数创建一个RSACryptoServiceProvider对象
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider;
然后,我们需要导出公钥和私钥,以便于存储和传输。可以使用RSA.ExportRSAPublicKey
方法和RSA.ExportRSAPrivateKey
方法来导出公钥和私钥,它们会返回一个字节数组,表示公钥和私钥的二进制格式。例如:
// 创建一个 RSA 对象
RSA rsa = RSA.Create;
rsa.KeySize = 2048;
/********可保存到文件或数据库*********/
// 导出公钥
byte publicKey = rsa.ExportRSAPublicKey;
// 导出私钥
byte privateKey = rsa.ExportRSAPrivateKey;
/********创建RSA对象存储密钥*********/
// 导出公钥
RSAParameters publicKeyParameters = rsa.ExportParameters(false);
// 导出私钥
RSAParameters privateKeyParameters = rsa.ExportParameters(true);
// 创建一个新的RSA对象,用于存储公钥
RSA publicKey = RSA.Create;
// 导入公钥参数
publicKey.ImportParameters(publicKeyParameters);
// 创建一个新的RSA对象,用于存储私钥
RSA privateKey = RSA.Create;
// 导入私钥参数
privateKey.ImportParameters(privateKeyParameters);
2、通过外部工具创建导入
首先,我们需要使用一些外部工具,例如OpenSSL或者Windows的证书管理器,来创建一个X.509
证书或者一个Pem
文件,它们包含了公钥和私钥。例如,通过以下的命令来使用OpenSSL创建一个X.509
证书:
# 生成一个私钥
openssl genrsa -out mykey.pem 2048
# 生成一个自签名的证书
openssl req -new -x509 -key mykey.pem -out mycert.pem -days 365
然后,使用以下的代码来从一个X.509
证书中导入公钥和私钥:
// 从一个文件中加载一个X.509证书
X509Certificate2 cert = new X509Certificate2("mycert.pfx", "password");
// 从X.509证书中获取RSA公钥
RSA publicKey = cert.GetRSAPublicKey;
// 从X.509证书中获取RSA私钥
RSA privateKey = cert.GetRSAPrivateKey
或者,使用以下的代码来从一个Pem
文件中导入公钥和私钥:
//公钥
string publicPem = "-----BEGIN PUBLIC KEY-----MIGfM……";
//私钥
string privatePem = "-----BEGIN PRIVATE KEY-----MIICdg……";
RSA publicKey = RSA.Create;
// 导入公钥
publicKey.ImportFromPem(publicPem);
RSA privateKey = RSA.Create;
//导入私钥
privateKey.ImportFromPem(privatePem);
二、创建和验证数字签名
无论我们是以编程方式生成密钥,还是通过外部工具创建导入,我们都可以使用相同的方法来使用密钥创建和验证数字签名。以下是具体的步骤:
首先,我们需要对文档进行哈希,以便于生成数字签名,可以使用SHA256
类来计算文档的哈希值,使用SHA256.ComputeHash
方法来对文档的字节数组进行哈希,它会返回一个字节数组,表示文档的哈希值。例如:
// 创建一个SHA256对象
SHA256 sha256 = SHA256.Create;
// 将文档转换为字节数组
byte document = Encoding.UTF8.GetBytes("Hello, this is a document that needs to be signed.");
// 对文档进行哈希
byte hash = sha256.ComputeHash(document);
然后,我们需要使用私钥对文档的哈希值进行加密,以生成数字签名。可以使用RSA.SignHash
方法来对文档的哈希值进行加密,它会返回一个字节数组,表示数字签名。同时指定哈希算法的名称和填充模式,这里我们使用SHA256
和Pkcs1
。例如:
// 使用私钥对文档的哈希值进行加密,生成数字签名
byte signature = privateKey.SignHash(hash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
最后,我们需要使用公钥对数字签名进行解密,以验证文档的完整性和来源。可以使用RSA.VerifyHash
方法来对数字签名进行解密,它会返回一个布尔值,表示验证的结果。同时指定相同的哈希算法名称和填充模式,例如:
// 使用公钥对数字签名进行解密,验证文档的完整性和来源
bool result = publicKey.VerifyHash(hash, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
如果result
为true
,说明文档没有被篡改,且来源可信,如果为false 说明文档可能被篡改,或者来源不可信。
数字签名可以保护文档的真实性和完整性,是安全文档管理的关键技术。通过ASP.NET Core,我们可以轻松地在应用程序中实现数字签名的功能。
参考资料:
https://stackoverflow.com/questions/50227580/create-x509certificate2-from-pem-file-in-net-core
https://stackoverflow.com/questions/243646/how-to-read-a-pem-rsa-private-key-from-net
https://stackoverflow.com/questions/52383226/specify-web-service-x509-certificate-endpoint-identity-in-net-core
https://github.com/dotnet/aspnetcore/issues/4706
文章出自猿惑豁微信公众号