как подписать CSR с помощью ключа ECDSA оболочки pkcs11 - PullRequest
1 голос
/ 17 апреля 2019

Я хочу сгенерировать пару ключей ECDSA в токене pkcs11 usb.после этого хотите подписать 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);

1 Ответ

1 голос
/ 19 апреля 2019

Для ECDSA вам не нужно DigestInfo, значение дайджеста (в байтах) подписывается напрямую. DigestInfo вероятно требуется для RSA.

...