PKCS#7格式數位簽章驗證
來源:互聯網
上載者:User
名詞解釋
數位簽章:在ISO7498-2標準中定義為:"附加在資料單元上的一些資料,或是對資料單元所作的密碼變換,這種資料和變換允許資料單元的接收者用以確認資料單元來源和資料單元的完整性,並保護資料,防止被人(例如接收者)進行偽造"。
PKCS#7:也叫做加密訊息的文法標準,由RSA安全體系在公開金鑰加密系統中交換數位憑證產生的一種加密標準。PKCS#7描述數位憑證的文法和其他加密訊息——尤其是,資料加密和數位簽章的方法,也包含了演算法。當使用PKCS#7進行數位簽章時,結果包含簽署憑證(一列相關認證撤回列表)和已證明路徑上任何其他認證。如果使用PKCS#7加密資料,通常包含發行者的參考訊息和認證的序號,它與用於解密已加密資料的公用密鑰相關。
PKCS#7標準定義了多種內容類型,包括下面這些:
·資料:位元組或8位元組串。
·簽名設計:隨加密資料摘要一起的資料。一個資訊摘要是一個雜湊演算法的結果(術語摘要和散列是相同定義的)。使用資訊摘要保證原始訊息在傳輸過程中沒有被篡改,並確認寄件者的身份。
·封裝資料:密文加上公開金鑰能夠解密資料。用這種方法保持訊息內容對所有人保密,都是信任收件者。
·簽名和加密資料:有公開金鑰的加密內容和雙重加密的訊息摘要。
·摘要資料:資料加上訊息摘要。
·單獨的加密資料:在這種情況,加密資料的公開金鑰必須通過其他機制傳輸。
實現方法
1、 使用java內建的安全性組件。由於jdk中沒有對PKCS#7格式簽名資料的處理。在做驗證時需要三個參數:原文;簽名資料和簽名者認證/簽名者公開金鑰,都是BASE64編碼。代碼如下:
public boolean SignedData_Verify(byte[] signData,byte[] signedData,byte[] cert) {
boolean verifyRet = true;
try {
// 建立Factory對象
CertificateFactory oCf = CertificateFactory.getInstance("X.509");
// 建立X509認證對象
InputStream ois = new ByteArrayInputStream(cert);
X509Certificate oCert = (X509Certificate)oCf.generateCertificate(ois);
// 建立簽名對象
Signature oSign = Signature.getInstance("SHA1withRSA");
// 初始化簽名對象
oSign.initVerify(oCert);
// 傳入簽名原文
oSign.update(signData);
// 驗證數位簽章
verifyRet = oSign.verify(signedData);
}
catch (Exception e) {
verifyRet = false;
e.printStackTrace();
System.out.println("驗證數位簽章失敗");
}
return verifyRet;
}
2、 通過bouncycastle的CMSSignedData可以實現pkcs#7格式簽名資料的驗證,利用CMSSignedData產生pkcs#7格式簽名資料。由於pkcs#7裡麵包含了原文和認證資訊,所以參數只需要簽名值即可。代碼如下:
public boolean SignedData_Verify(byte[] SignedData) {
boolean verifyRet = true;
try {
// 建立PKCS#7簽名資料處理對象
CMSSignedData sign = new CMSSignedData(signedData);
// 添加BouncyCastle作為安全提供
Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider());
// 獲得認證資訊
CertStore certs = sign.getCertificatesAndCRLs("Collection", "BC");
// 獲得簽名者資訊
SignerInformationStore signers = sign.getSignerInfos();
Collection c = signers.getSigners();
Iterator it = c.iterator();
// 當有多個簽名者資訊時需要全部驗證
while (it.hasNext()) {
SignerInformation signer = (SignerInformation) it.next();
// 憑證鏈結
Collection certCollection = certs.getCertificates(signer
.getSID());
Iterator certIt = certCollection.iterator();
X509Certificate cert = (X509Certificate) certIt.next();
// 驗證數位簽章
if (signer.verify(cert.getPublicKey(), "BC")) {
verifyRet = true;
} else {
verifyRet = false;
}
}
}
catch (Exception e) {
verifyRet = false;
e.printStackTrace();
System.out.println("驗證數位簽章失敗");
}
return verifyRet;
}