java生成电子证书_java – 如何用x509证书生成数字签名?

本文档详细介绍了如何在Java中使用IAIK PKCS11库和安全令牌的密钥库来生成X509证书,并创建XML签名。关键步骤包括获取XML文档对象、初始化XML签名工厂、设置参考和签名信息、创建KeyInfo,以及最终签署XML文档。
摘要由CSDN通过智能技术生成

我知道问题已经有一段时间了,但我有同样的问题,我解决了,所以我想分享解决方案它使用从安全令牌获得的密钥库使用iaik pkcs工具:

用于替换singletonList的技巧

KeyInfo ki =

kif.newKeyInfo(Collections.singletonList(kv));

对于包含证书和keyvalue的列表.

整个魔法的代码(希望它可以帮助某人):

public void generateSignatureforResumen(String originalXmlFilePath,

String destnSignedXmlFilePath, IAIKPkcs11 pkcs11Provider_, KeyStore tokenKeyStore, String pin) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, GeneralSecurityException, TokenException {

//Get the XML Document object

Document doc = getXmlDocument(originalXmlFilePath);

//Create XML Signature Factory

PrivateKey signatureKey_ = null;

PublicKey pubKey_ = null;

X509Certificate signingCertificate_ = null;

Boolean prik = false;

Boolean pubk = false;

Enumeration aliases = tokenKeyStore.aliases();

while (aliases.hasMoreElements()) {

String keyAlias = aliases.nextElement().toString();

java.security.Key key = tokenKeyStore.getKey(keyAlias, pin.toCharArray());

if (key instanceof java.security.interfaces.RSAPrivateKey) {

Certificate[] certificateChain = tokenKeyStore.getCertificateChain(keyAlias);

X509Certificate signerCertificate = (X509Certificate) certificateChain[0];

boolean[] keyUsage = signerCertificate.getKeyUsage();

// check for digital signature or non-repudiation,

// but also accept if none is set

if ((keyUsage == null) || keyUsage[0] || keyUsage[1]) {

signatureKey_ = (PrivateKey) key;

signingCertificate_ = signerCertificate;

prik = true;

pubKey_ = signerCertificate.getPublicKey();

break;

}

}

}

if (signatureKey_ == null) {

throw new GeneralSecurityException(

"Found no signature key. Ensure that a valid card is inserted.");

}

XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM");

Reference ref = null;

SignedInfo signedInfo = null;

try {

ref = xmlSigFactory.newReference("", xmlSigFactory.newDigestMethod(DigestMethod.SHA1, null),

Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED,

(TransformParameterSpec) null)), null, null);

signedInfo = xmlSigFactory.newSignedInfo(

xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,

(C14NMethodParameterSpec) null),

xmlSigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null),

Collections.singletonList(ref));

} catch (NoSuchAlgorithmException ex) {

ex.printStackTrace();

}

KeyInfoFactory kif = xmlSigFactory.getKeyInfoFactory();

X509Data x509data = kif.newX509Data(Collections.nCopies(1, signingCertificate_));

KeyValue kval = kif.newKeyValue(pubKey_);

List keyInfoItems = new ArrayList();

keyInfoItems.add(kval);

keyInfoItems.add(x509data);

//Object list[];

KeyInfo keyInfo = kif.newKeyInfo(keyInfoItems);

//Create a new XML Signature

XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo, keyInfo);

DOMSignContext domSignCtx = new DOMSignContext((Key) signatureKey_, doc.getDocumentElement());

try {

//Sign the document

xmlSignature.sign(domSignCtx);

} catch (MarshalException ex) {

ex.printStackTrace();

} catch (XMLSignatureException ex) {

ex.printStackTrace();

}

//Store the digitally signed document inta a location

storeSignedDoc(doc, destnSignedXmlFilePath);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以使用数字签名技术来实现电子合同签名,具体步骤如下: 1. 生成公私钥对 首先需要生成公私钥对,可以使用Java提供的KeyPairGenerator类来生成,示例代码如下: ``` KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); ``` 2. 对原始数据进行哈希 使用SHA256算法对原始数据进行哈希处理,得到哈希值,示例代码如下: ``` MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(data.getBytes("UTF-8")); byte[] hash = messageDigest.digest(); ``` 3. 使用私钥对哈希值进行签名 使用私钥对哈希值进行数字签名,可以使用Java提供的Signature类来实现,示例代码如下: ``` Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(privateKey); signature.update(hash); byte[] signatureBytes = signature.sign(); ``` 4. 验证签名 使用公钥对签名进行验证,如果验证通过,说明签名是有效的,示例代码如下: ``` Signature signature = Signature.getInstance("SHA256withRSA"); signature.initVerify(publicKey); signature.update(hash); boolean verified = signature.verify(signatureBytes); ``` 这样就可以使用Java实现电子合同签名了。需要注意的是,签名过程中需要保证私钥的安全性,签名后的数据可以与原始数据一起存储,以便后续验证签名的有效性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值