我想在pkcs11 usb令牌中生成ECDSA密钥对。之后,想要使用私钥对CSR进行签名,但是要面对“无效签名”异常。
Mechanism keyPairGenerationMechanism = Mechanism.get(PKCS11Constants.CKM_EC_KEY_PAIR_GEN);
ECDSAPrivateKey ecdsaPrivateKeyTemplate = new ECDSAPrivateKey();
ecdsaPrivateKeyTemplate.getLabel().setCharArrayValue(keyAlias.toCharArray());
ecdsaPrivateKeyTemplate.getId().setByteArrayValue(keyAlias.getBytes());
ecdsaPrivateKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
ecdsaPrivateKeyTemplate.getDecrypt().setBooleanValue(Boolean.TRUE);
ecdsaPrivateKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
ecdsaPrivateKeyTemplate.getPrivate().setBooleanValue(Boolean.TRUE);
ecdsaPrivateKeyTemplate.getSensitive().setBooleanValue(Boolean.TRUE);
ecdsaPrivateKeyTemplate.getExtractable().setBooleanValue(Boolean.FALSE);
ecdsaPrivateKeyTemplate.getKeyType().setLongValue(PKCS11Constants.CKK_EC); ECDSAPublicKey ecdsaPublicKeyTemplate = new ECDSAPublicKey(); ecdsaPublicKeyTemplate.getLabel().setCharArrayValue(keyAlias.toCharArray());
ecdsaPublicKeyTemplate.getId().setByteArrayValue(keyAlias.getBytes());
ecdsaPublicKeyTemplate.getEncrypt().setBooleanValue(Boolean.TRUE);
ecdsaPublicKeyTemplate.getPrivate().setBooleanValue(Boolean.FALSE);
ecdsaPublicKeyTemplate.getVerify().setBooleanValue(Boolean.TRUE);
ecdsaPublicKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
ecdsaPublicKeyTemplate.getKeyType().setLongValue(PKCS11Constants.CKK_EC);
ecdsaPublicKeyTemplate.getModifiable().setBooleanValue(Boolean.TRUE);
ASN1ObjectIdentifier curveId = getCurveId((getEcdsaParamsOID(256)));
X962Parameters x962 = new X962Parameters(curveId);
byte[] paramsBytes = x962.getEncoded();
ecdsaPublicKeyTemplate.getEcdsaParams().setByteArrayValue(paramsBytes);
KeyPair generatedKeyPair = m_objSession.generateKeyPair(keyPairGenerationMechanism,ecdsaPublicKeyTemplate, ecdsaPrivateKeyTemplate);
ECDSAPublicKey publicKey = (ECDSAPublicKey) generatedKeyPair.getPublicKey();
ECDSAPrivateKey privateKey = (ECDSAPrivateKey) generatedKeyPair.getPrivateKey();
byte[] pubPoint = publicKey.getEcPoint().getByteArrayValue();
DEROctetString os = (DEROctetString) DEROctetString.fromByteArray(pubPoint);
AlgorithmIdentifier keyAlgID = new AlgorithmIdentifier(
X9ObjectIdentifiers.id_ecPublicKey, curveId);
SubjectPublicKeyInfo pkInfo = new SubjectPublicKeyInfo(keyAlgID, os.getOctets());
从注释中签名代码:
ECDSAPrivateKey signatureKey = this.getECDSAPrivateKey(a_strKeyId,m_objSession);
MessageDigest digestEngine = MessageDigest.getInstance("SHA-256");
digestEngine.update(bUnsignedData);
byte[] digest = digestEngine.digest();
Mechanism signatureMechanism = Mechanism.get(PKCS11Constants.CKM_ECDSA);
m_objSession.signInit(signatureMechanism, signatureKey);
DigestInfo digestInfoEngine = new DigestInfo(a_objAlgorithmIdentifier, digest);
byte[] digestInfo = digestInfoEngine.getEncoded();
byte[] signatureValue = m_objSession.sign(digestInfo);
答案 0 :(得分:1)
对于ECDSA,您不需要DigestInfo
,摘要值(以字节为单位)将直接签名。 RSA可能需要DigestInfo
。