解決用SHA256算法做私鑰簽名時,遇到“指定的算法無效”的問題


在上一篇隨筆“記一次三方接口開發的數據加密方案”中,使用SHA256對數據進行簽名時,我提到了一個異常,System.Security.Cryptography.CryptographicException "Invalid algorithm specified.",中文為“指定的算法無效”。自己用openssl命令生成的證書沒有這個問題,但是網站上導出的免費證書不行,對此不想過多糾結。但是,后來使用從CFCA申請的證書,居然也不行,所以不得不對這個問題做了更深入的探究。順便以此為切入點,學習下使用openssl命令操作證書。

 一、產生原因

針對證書私鑰采用SHA256算法對數據進行簽名時,報“指定的算法無效”這一異常,我查詢了不少資料,才找到問題原因,在百度上幾乎什么有用的信息也搜不出來,在google上翻閱了多篇文章,才弄清楚問題的根本。 

實際原因是RSACryptoServiceProvider依賴底層CryptoAPI來完成其工作,只有CrytoAPI支持SHA256算法的Windows版本才會啟用此功能,這意味着它取決於我們用來執行加密操作的CSP(加密服務提供程序)。因為Microsoft CSP是在Rsaenh.dll上實現的,所以當我們使用SHA256對數據做簽名時,函數CryptCreateHash將在后台被CALG_SHA_256的ALG_ID調用。此加密API本身不執行加密操作。它將從應用程序獲得的參數重定向到所需的CSP,並且CSP代表它執行操作。所以我們得到的錯誤實際上來自於CSP。

因此,為了檢查我們是否可以使用SHA256,我們必須確保:

  1. 您的證書必須在支持SHA256的情況下生成。
  2. 用於生成證書的CSP必須支持SHA256。

 二、解決方案

針對第1種情況,生成證書時我們會指定SHA256簽名算法,所以只要生成了證書就不會有問題。

我們的問題主要是出於第2種情況,生成證書指定的CSP要支持SHA256,而windows上默認導出生成的pfx文件,卻沒有顯式指定CSP。

我用openssl命令生成pfx時,指定了-CSP "Microsoft Enhanced RSA and AES Cryptographic Provider",所以為什么網站上申請的證書導出的pfx不支持SHA256,根本差異就在這里。

可以通過注冊表查看系統支持的CSP,位置在HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Defaults\Provider,如圖

所以最終,我們的思路就是拿到證書后,用openssl命令來重新生成pfx證書,在命令中指定CSP。

在線申請證書及導出后,我們擁有test.cer和test.pfx兩個證書文件。

然后使用以下三個命令導出新的pfx證書文件。

1 //step1,pfx轉pem
2 openssl pkcs12 -in test.pfx -nodes -out test.pem
3 //step2,pem轉key
4 openssl rsa -in test.pem -out test.key
5 //step3,合成新的pfx
6 openssl pkcs12 -export -in test.cer -inkey test.key -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -out test2.pfx

最終重新生成的test2.pfx,就可以使用SHA256算法做私鑰簽名了。

openssl命令詳解:

  • step1,pfx是包含公鑰和私鑰的二進制格式證書文件,有口令保護,所以執行命令時,會要求輸入密碼,導出的pem為base64編碼格式的證書文件,同樣包括公鑰和私鑰;
  • step2,pem導出key,key為base64編碼的私鑰證書文件,rsa為密鑰的加密算法,如果是dsa,就寫dsa;
  • step3,將base64編碼格式的cer和key文件,就是公鑰和私鑰文件,合成二進制格式pfx文件,指定CSP。這里的cer文件要求必須是base64編碼格式的,否則會報錯提示“unable to load certificates”,也就是說你的cer文件是二進制格式的。當然,這里輸入的公鑰采用base64編碼格式的pem公鑰文件也是可以的。

 三、基礎知識

為了更好的理解學習操作證書的openssl命令,需要了解證書格式的一些基本知識。

CA中心普遍采用的規范是X.509系列和PKCS(Public Key Cryptography Standards)系列(證書格式系列標准含義很豐富,具體標准可自行查詢),主要用的證書格式標准:

  • x509,公鑰證書

  • pcks#12,描述個人信息交換語法標准,包含公鑰和私鑰,有口令保護

編碼方式:

  • DER(二進制)編碼
  • BASE64(ASCII)編碼

證書文件格式:

  • csr,用於向CA申請簽名的請求文件格式
  • cer或crt,公鑰證書,編碼方式不定,多用於Windows
  • key,公鑰或私鑰,編碼方式不定
  • pem,公或私或公私鑰,BASE64編碼格式,多用於Linux
  • pfx,包括公私鑰,DER編碼二進制格式,多用於Windows

openssl常用命令知識:

  • cer公鑰證書為x509標准格式,pfx私鑰證書為PKCS#12標准格式
  • 公鑰是由私鑰生成的,openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
  • 查看base64編碼格式公鑰證書,openssl x509 -in test.cer -noout -text
  • Linux下多用pem格式,cer轉pem,openssl x509 -in test.cer -out test.pem
  • 查看pfx私鑰證書,應先轉為pem格式,即由PKCS#12格式DER二進制編碼轉換為BASE64編碼后查看,openssl pkcs12 -in test.pfx -nodes -out test.pem
  • 查看pem證書,openssl rsa -in test.pem -text
  • -noout 參數即無文件輸出,-nodes 參數即無算法加密

 

參考(查到這篇文章直接解決了本文的問題):https://hintdesk.com/2011/07/29/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/

-- End


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM