1

Я делаю сертификат X509 с библиотекой Bouncy Castle на Java. Мне нужно установить атрибут ключа для закрытого ключа.

PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1024
Bag Attributes
    friendlyName: ASDF
    localKeyID: XX XX XX XX
    Microsoft CSP Name: Microsoft Software Key Storage Provider  <--- (1)
Key Attributes: <No Attributes>    <--- put HERE X509v3 Key Usage: 80
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

Мне нужно установить Key Usage на 80 -> X509v3 Key Usage: 80. Потому что я работаю с эллиптической кривой и Windows Maquine не распознает, если не имеют этих атрибутов.

Я попробовал с:

X509v3CertificateBuilder builder =  new JcaX509v3CertificateBuilder(
                issuerDNName, 
                serial,
                startDate, 
                endDate, 
                tX500Name, 
                pubKey);

X509KeyUsage usage = new X509KeyUsage(X509KeyUsage.digitalSignature); 
builder.addExtension(Extension.keyUsage, false, usage); 

или же

builder.addExtension(
                new ASN1ObjectIdentifier("2.5.29.15"),
                true,
                new X509KeyUsage(
                   X509KeyUsage.digitalSignature));

Ни один не работает. Я могу установить Bag Attribute (1) так:

PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privateKey;//pbeWithSHA1And3-KeyTripleDES-CBC
        bagAttr.setBagAttribute(
                MicrosoftObjectIdentifiers.microsoft.branch("17").branch("1"),// this OID corresponds to: 1.3.6.1.4.1.311.17.1
                new DERBMPString("Microsoft Software Key Storage Provider"));

Существует класс PrivateKeyInfo, но я не знаю, как его использовать.

если я делаю с openssl, мне нужно поставить опцию -keysig .

openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -name "MY CERTIFICATE" -certfile demoCA/cacert.pem -out mycert.p12 -keysig

OpenSSL Docs

-keyex | -keysig указывает, что закрытый ключ должен использоваться для обмена ключами или только для подписи. Эта опция интерпретируется только MSIE и аналогичным программным обеспечением MS. Обычно программное обеспечение "экспортного качества" позволяет использовать только 512-битные ключи RSA для шифрования, но ключи произвольной длины для подписи. Опция -keysig отмечает ключ только для подписи. Ключи только для подписи могут использоваться для подписи S/MIME, authenticode (подписи элемента управления ActiveX) и аутентификации клиента SSL, однако из-за ошибки только MSIE 5.0 и более поздних версий поддерживают использование только ключей подписи для аутентификации клиента SSL.

Результат:

PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Bag Attributes
    localKeyID: XX XX XX XX
    friendlyName: ASDF
    Microsoft CSP Name: ECDSA_P256#Microsoft Software key Service Provider
Key Attributes
    X509v3 Key Usage: 80     <-- This
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

Спасибо!

1 ответ1

1

Слегка измененный код создания pkcs12 с ключевым атрибутом приведен ниже.

private static void createPKCS12File(String alias, PrivateKey key,
X509Certificate cert, char[] password, OutputStream pfxOut)
throws Exception
{
    PrivateKeyInfo pki = PrivateKeyInfo.getInstance(key.getEncoded());
    X509KeyUsage usage = new X509KeyUsage(X509KeyUsage.digitalSignature);
    DERSet usageSet = new DERSet(usage);
    DERSequence attrib = new DERSequence(new ASN1Encodable[]
        {new ASN1ObjectIdentifier("2.5.29.15"), usageSet});
    pki = new PrivateKeyInfo(pki.getPrivateKeyAlgorithm(),
        pki.parsePrivateKey(), new DLSet(attrib));

    OutputEncryptor encOut = new JcePKCSPBEOutputEncryptorBuilder(
        NISTObjectIdentifiers.id_aes256_CBC).setProvider("BC").build(
        password);
    PKCS12SafeBagBuilder certBuilder = new JcaPKCS12SafeBagBuilder(
        cert);
    certBuilder.addBagAttribute(
        PKCS12SafeBag.friendlyNameAttribute, new DERBMPString(alias));

    JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
    SubjectKeyIdentifier pubKeyId = extUtils.createSubjectKeyIdentifier(
        cert.getPublicKey());
    certBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute,
        pubKeyId);
    PKCS12SafeBagBuilder keyBagBuilder = new PKCS12SafeBagBuilder(pki,
        encOut);
    keyBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute,
        new DERBMPString(alias));
    keyBagBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute,
        pubKeyId);
    keyBagBuilder.addBagAttribute(new ASN1ObjectIdentifier(
        "1.3.6.1.4.1.311.17.1"),
        new DERBMPString("Microsoft Software Key Storage Provider"));
    PKCS12PfxPduBuilder builder = new PKCS12PfxPduBuilder();
    builder.addData(keyBagBuilder.build());
    builder.addEncryptedData(new JcePKCSPBEOutputEncryptorBuilder(
        PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC).
        setProvider("BC").build(password),
        new PKCS12SafeBag[]{certBuilder.build()});
    PKCS12PfxPdu pfx = builder.build(new JcePKCS12MacCalculatorBuilder(
        NISTObjectIdentifiers.id_sha256), password);
    pfxOut.write(pfx.getEncoded(ASN1Encoding.DL));
    pfxOut.flush();
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .