日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET Core加解密实战系列之——使用BouncyCastle制作p12(.pfx)数字证书

發(fā)布時間:2023/12/4 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core加解密实战系列之——使用BouncyCastle制作p12(.pfx)数字证书 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

簡介

加解密現(xiàn)狀,編寫此系列文章的背景:

  • 需要考慮系統(tǒng)環(huán)境兼容性問題(Linux、Windows)

  • 語言互通問題(如C#、Java等)(加解密本質上沒有語言之分,所以原則上不存在互通性問題)

  • 網上資料版本不一、或不全面

  • .NET官方庫密碼算法提供不全面,很難針對其他語言(Java)進行適配

本系列文章主要介紹如何在 .NET Core 中使用非對稱加密算法、編碼算法、消息摘要算法、簽名算法、對稱加密算法、國密算法等一系列算法,如有錯誤之處,還請大家批評指正。

本系列文章旨在引導大家能快速、輕松的了解接入加解密,乃至自主組合搭配使用BouncyCastle密碼術包中提供的算法。

本系列代碼項目地址:https://github.com/fuluteam/ICH.BouncyCastle.git

上一篇文章《.NET Core加解密實戰(zhàn)系列之——對稱加密算法》:https://www.cnblogs.com/fulu/p/13650079.html

功能依賴

BouncyCastle(https://www.bouncycastle.org/csharp) 是一個開放源碼的輕量級密碼術包;它支持大量的密碼術算法,它提供了很多 .NET Core標準庫沒有的算法。

支持 .NET 4,.NET Standard 1.0-2.0,WP,Silverlight,MonoAndroid,Xamarin.iOS,.NET Core

功能依賴
Portable.BouncyCastlePortable.BouncyCastle ? 1.8.6

前言

在工作中我們難免會接觸對接外部系統(tǒng)(如銀行、支付寶、微信等),對接過程中又無可避免會對數據的加解密和加簽驗簽。一般第三方會提供一個授權證書,讓我們自行解密提取秘鑰。為了讓你拿到證書后不會像我當初一樣一臉懵逼,咱們來看看如何使用C#代碼制作使用p12證書。

當然,比較常見的,還是推薦大家使用OpenSSL。

OpenSSL是目前最流行的 SSL密碼庫工具,其提供了一個通用、健壯、功能完備的工具套件,用以支持SSL/TLS 協(xié)議的實現(xiàn)。
官網:https://www.openssl.org/source/

什么是p12證書

公鑰加密技術12號標準(Public Key Cryptography Standards #12,PKCS#12)為存儲和傳輸用戶或服務器私鑰、公鑰和證書指定了一個可移植的格式。它是一種二進制格式,這些文件也稱為PFX文件。

P12證書包含了私鑰、公鑰并且有口令保護,在證書泄露后還有最后一道保障。沒有證書口令無法提取秘鑰。
對PKCS標準感興趣的小伙伴可以參考百度百科PKCS介紹

什么是X.509格式

在密碼學中,X.509是定義公鑰證書格式的標準。X.509證書用于許多Internet協(xié)議,包括TLS/SSL,它是HTTPS(用于瀏覽web的安全協(xié)議)的基礎。它們也用于離線應用程序,比如電子簽名。一個X.509證書包含一個公鑰和一個標識(主機名、組織或個人),由證書頒發(fā)機構簽名或自簽名。當證書由受信任的證書頒發(fā)機構簽名時,或者通過其他方法進行驗證時,持有該證書的人可以依賴于它包含的公鑰來與另一方建立安全通信,或者驗證由相應私鑰數字簽名的文檔。

X.509還定義了證書撤銷列表,這是一種分發(fā)被簽名機構認為無效的證書信息的方法,以及認證路徑驗證算法,該算法允許證書由中間CA證書簽名,而中間CA證書又由其他證書簽名,最終到達信任錨。

X.509由國際電信聯(lián)盟標準化部門(ITU-T)定義,并基于ITU-T的另一個標準ASN.1。

SSL Certificate (編碼)格式

SSL Certificate實際上就是X.509 Certificate。X.509是一個定義了certificate結構的標準。它在SSL certificate中定義了一個數據域。X.509使用名為 Abstract Syntax Notation One (ASN.1)的通用語言來描述certificate的數據結構。

X.509 certificate 有幾種不同的格式,例如 PEM,DER,PKCS#7 和 PKCS#12。PEM和PKCS#7格式使用Base64 ASCII編碼,而DER和PKCS#12使用二進制編碼。certificate文件基于不同的編碼格式有不同的文件擴展名。

如下圖就展示了X.509證書的編碼方式和文件擴展名。

X.509 證書結構

X.509證書的結構是用ASN.1(Abstract Syntax Notation One:抽象語法標記)來描述其數據結構,并使用ASN1語法進行編碼。

  • X.509 v3數字證書的結構如下:

  • certificate 證書

  • Version Number版本號

  • Serial Number序列號

  • ID Signature Algorithm ID簽名算法

  • Issuer Name頒發(fā)者名稱

  • Validity period 有效期

  • Not before起始日期

  • Not after截至日期

  • Subject Name主題名稱

  • Subject pbulic Key Info 主題公鑰信息

  • Public Key Algorithm公鑰算法

  • Subject Public Key主題公鑰

  • Issuer Unique Identifier (optional)頒發(fā)者唯一標識符(可選)

  • Subject Unique Identifier (optional)主題唯一標識符(可選)

  • Extensions (optional) 證書的擴展項(可選)

  • Certificate Sigature Algorithm證書簽名算法

  • Certificate Signature證書的簽名

證書操作

證書生成

/// <summary>/// 生成證書/// </summary>/// <param name="notAfter">證書失效時間</param>/// <param name="keyStrength">密鑰長度</param>/// <param name="password">證書密碼</param>/// <param name="signatureAlgorithm">設置將用于簽署此證書的簽名算法</param>/// <param name="issuer">設置此證書頒發(fā)者的DN</param>/// <param name="subject">設置此證書使用者的DN</param>/// <param name="friendlyName">設置證書友好名稱(可選)</param>/// <param name="notBefore">證書生效時間</param>public static void GenerateCertificate(string filename, string password, string signatureAlgorithm, X509Name issuer, X509Name subject, DateTime notBefore, DateTime notAfter, string friendlyName, int keyStrength = 2048){SecureRandom random = new SecureRandom(new CryptoApiRandomGenerator());var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);var keyPairGenerator = new RsaKeyPairGenerator(); //RSA密鑰對生成器keyPairGenerator.Init(keyGenerationParameters);var subjectKeyPair = keyPairGenerator.GenerateKeyPair();ISignatureFactory signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, subjectKeyPair.Private, random);//the certificate generatorX509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();var spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public);//設置一些擴展字段//允許作為一個CA證書(可以頒發(fā)下級證書或進行簽名)certificateGenerator.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));//使用者密鑰標識符certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifier(spki));//授權密鑰標識符certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifier(spki));certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));//證書序列號BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);certificateGenerator.SetSerialNumber(serialNumber);certificateGenerator.SetIssuerDN(issuer); //頒發(fā)者信息certificateGenerator.SetSubjectDN(subject); //使用者信息certificateGenerator.SetNotBefore(notBefore); //證書生效時間certificateGenerator.SetNotAfter(notAfter); //證書失效時間certificateGenerator.SetPublicKey(subjectKeyPair.Public);Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);//生成cer證書,公鑰證書//var certificate2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(certificate))//{// FriendlyName = friendlyName, //設置友好名稱//};cer公鑰文件//var bytes = certificate2.Export(X509ContentType.Cert);//using (var fs = new FileStream(certPath, FileMode.Create))//{// fs.Write(bytes, 0, bytes.Length);//}//另一種代碼生成p12證書的方式(要求使用.net standard 2.1)//certificate2 =// certificate2.CopyWithPrivateKey(DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private));//var bytes2 = certificate2.Export(X509ContentType.Pfx, password);//using (var fs = new FileStream(pfxPath, FileMode.Create))//{// fs.Write(bytes2, 0, bytes2.Length);//}var certEntry = new X509CertificateEntry(certificate);var store = new Pkcs12StoreBuilder().Build();store.SetCertificateEntry(friendlyName, certEntry); //設置證書var chain = new X509CertificateEntry[1];chain[0] = certEntry;store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain); //設置私鑰using (var fs = File.Create(filename)){store.Save(fs, password.ToCharArray(), random); //保存};}private static void Certificate_Sample(){//頒發(fā)者DNvar issuer = new X509Name(new ArrayList{X509Name.C,X509Name.O,X509Name.OU,X509Name.L,X509Name.ST}, new Hashtable{[X509Name.C] = "CN",[X509Name.O] = "Fulu Newwork",[X509Name.OU] = "Fulu RSA CA 2020",[X509Name.L] = "Wuhan",[X509Name.ST] = "Hubei",});//使用者DNvar subject = new X509Name(new ArrayList{X509Name.C,X509Name.O,X509Name.CN}, new Hashtable{[X509Name.C] = "CN",[X509Name.O] = "ICH",[X509Name.CN] = "*.fulu.com"});var password = "123456"; //證書密碼var signatureAlgorithm = "SHA256WITHRSA"; //簽名算法//生成證書CertificateUtilities.GenerateCertificate("fuluca.pfx", password, signatureAlgorithm, issuer, subject, DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddYears(2), "fulu passport");//加載證書X509Certificate2 pfx = new X509Certificate2("fuluca.pfx", password, X509KeyStorageFlags.Exportable);var keyPair = DotNetUtilities.GetKeyPair(pfx.PrivateKey);var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);var privateKey = Base64.ToBase64String(privateKeyInfo.ParsePrivateKey().GetEncoded());var publicKey = Base64.ToBase64String(subjectPublicKeyInfo.GetEncoded());Console.ForegroundColor = ConsoleColor.DarkYellow;Console.WriteLine("Pfx證書私鑰:");Console.WriteLine(privateKey);Console.WriteLine("Pfx證書公鑰:");Console.WriteLine(publicKey);var data = "hello rsa";Console.WriteLine($"加密原文:{data}");var pkcs1data = RSA.EncryptToBase64(data, AsymmetricKeyUtilities.GetAsymmetricKeyParameterFormPublicKey(publicKey), Algorithms.RSA_ECB_PKCS1Padding);Console.WriteLine("加密結果:");Console.WriteLine(pkcs1data);Console.WriteLine("解密結果:");var datares = RSA.DecryptFromBase64(pkcs1data,AsymmetricKeyUtilities.GetAsymmetricKeyParameterFormPrivateKey(privateKey), Algorithms.RSA_ECB_PKCS1Padding);Console.WriteLine(datares);}

生成的證書文件:

證書安裝

雙擊證書文件進行安裝,存儲位置選擇當前用戶。

證書存儲選擇個人

查看安裝的證書

可以在MMC的證書管理單元中對證書存儲區(qū)進行管理。Windows沒有給我們準備好直接的管理證書的入口。自己在MMC中添加,步驟如下:

  • 開始→運行→MMC,打開一個空的MMC控制臺。

  • 在控制臺菜單,文件→添加/刪除管理單元→添加按鈕→選”證書”→添加→選”我的用戶賬戶”→關閉→確定

  • 展開 證書控制臺根節(jié)點→證書-當前用戶→個人→證書,找到證書,可以看到下圖中選中的即為我們創(chuàng)建的證書文件

    雙擊證書,可以看到證書的相關信息

    OpenSSL安裝

    工具:openssl

    安裝軟件:Win64 OpenSSL v1.1.1g Light

    下載地址:http://slproweb.com/products/Win32OpenSSL.html

    PFX文件提取公鑰私鑰

    openssl pkcs12 -in fulusso.pfx -nocerts -nodes -out private.key輸入密碼openssl rsa -in private.key -out pfx_pri.pemopenssl rsa -in private.key -pubout -out pfx_pub.pem

    安裝好OpenSSL后,打開Win64 OpenSSL Command Prompt,讀取到證書文件所在目錄,按上述命令執(zhí)行

    打開證書所在目錄,可以看到文件 private.key、pfx_pri.pem、pfx_pub.pem 已經生成好了。

    用文本工具打開私鑰文件pfx_pri.pem,如下圖:

    打開公約文件pfx_pub.pem,如下圖:

    比對與上文控制臺打印出的公鑰、私鑰一致。

    下期預告

    下一篇將介紹國密算法,敬請期待。。。

    ?

    總結

    以上是生活随笔為你收集整理的.NET Core加解密实战系列之——使用BouncyCastle制作p12(.pfx)数字证书的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。