1

I make a certificate X509 with library Bouncy Castle on Java. I need set a Key Attribute to private key.

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-----

I need set Key Usage to 80 --> X509v3 Key Usage: 80. Because I work with eliptic curve and windows maquine not recognoize if don't have those attributes.

I did try with:

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

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

or

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

Any don't work. I can set a Bag Attribute (1) so:

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"));

Exists a PrivateKeyInfo Class but I don't how to use this.

if I make with openssl, I need put -keysig option.

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

OpenSSL Docs

-keyex|-keysig specifies that the private key is to be used for key exchange or just signing. This option is only interpreted by MSIE and similar MS software. Normally "export grade" software will only allow 512 bit RSA keys to be used for encryption purposes but arbitrary length keys for signing. The -keysig option marks the key for signing only. Signing only keys can be used for S/MIME signing, authenticode (ActiveX control signing) and SSL client authentication, however due to a bug only MSIE 5.0 and later support the use of signing only keys for SSL client authentication.

Result:

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-----

Thanks!

1 Answers1

2

Slightly modified pkcs12 creation code with key attrib is given below.

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();
}