Sample code for 30+ languages & platforms
PureBasic

Convert Java KeyStore to PKCS12 / PFX

See more Java KeyStore (JKS) Examples

Loads a Java keystore file and saves it as a PKCS12 / PFX. A Java keystore (JKS) can contain two types of entries: (1) trusted root certificates or (2) private keys + cert chains. Usually a JKS will contain all entries of one type or another (and thus a particular JKS serves one purpose or another; meaning that a JKS containing trusted roots is used as a source for verifying pre-trusted roots, and a JKS containing private keys (and cert chains) is used as a secure, encrypted store for private keys).

A PKCS12 / PFX typically contains one or more private keys, along with each private key's certificate chain. Therefore, it typically makes sense to only write the private key entries to a PKCS12 (and the associated certificate chains). If a JKS contains trusted root certificates, it makes more sense to conver it to a PEM file (such as the CA cert bundle in PEM format from mozilla.org).

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkPrivateKey.pb"
IncludeFile "CkCertChain.pb"
IncludeFile "CkJavaKeyStore.pb"
IncludeFile "CkPfx.pb"

Procedure ChilkatExample()

    success.i = 0

    ; This requires the Chilkat API to have been previously unlocked.
    ; See Global Unlock Sample for sample code.

    jks.i = CkJavaKeyStore::ckCreate()
    If jks.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    jksPassword.s = "myJksPassword"

    ; Load the Java keystore from a file.  The JKS file password is used
    ; to verify the keyed digest that is found at the very end of the keystore.
    ; It verifies that the keystore has not been modified.
    success = CkJavaKeyStore::ckLoadFile(jks,jksPassword,"/someDir/keyStore.jks")
    If success <> 1
        Debug CkJavaKeyStore::ckLastErrorText(jks)
        CkJavaKeyStore::ckDispose(jks)
        ProcedureReturn
    EndIf

    ; To convert, we'll access the private key entries
    ; from the JKS, add each to the PKCS12, and then save the PKCS12.
    pkcs12.i = CkPfx::ckCreate()
    If pkcs12.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    numPrivateKeys.i = CkJavaKeyStore::ckNumPrivateKeys(jks)
    i.i

    privKey.i
    certChain.i

    ; For each private key entry, get the private key and
    ; the associated certificate chain.
    ; Each private key is password protected.  Usually it is the same
    ; password as used for the keyed digest of the entire JKS.  
    ; However, this does not have to be.  The password is passed
    ; here to handle the possibility of each private key requiring
    ; a different password.
    i = 0
    While i < numPrivateKeys
        privKey = CkJavaKeyStore::ckGetPrivateKey(jks,jksPassword,i)
        Debug CkJavaKeyStore::ckGetPrivateKeyAlias(jks,i)
        certChain = CkJavaKeyStore::ckGetCertChain(jks,i)

        ; Add the private key and it's associated certificate chain to the PKCS12.
        success = CkPfx::ckAddPrivateKey(pkcs12,privKey,certChain)
        If success <> 1
            Debug CkPfx::ckLastErrorText(pkcs12)
            CkCertChain::ckDispose(certChain)

            CkPrivateKey::ckDispose(privKey)

            CkJavaKeyStore::ckDispose(jks)
            CkPfx::ckDispose(pkcs12)
            ProcedureReturn
        EndIf

        CkCertChain::ckDispose(certChain)

        CkPrivateKey::ckDispose(privKey)

        i = i + 1
    Wend

    ; Save the PKCS12 / PFX to a file.
    ; The password can be the same as the JKS password, or something new.
    ; (With the PKCS12 format, there is a single password for the entire contents
    ; of the file.  With the JKS format, there is flexibility in allowing each private key
    ; to have it's own password.)
    pkcs12Password.s = "myNewPassword"
    success = CkPfx::ckToFile(pkcs12,pkcs12Password,"/pkcs12_files/myPfx.p12")
    If success <> 1
        Debug CkPfx::ckLastErrorText(pkcs12)
    Else
        Debug "Successfully saved to PKCS12 format."
    EndIf



    CkJavaKeyStore::ckDispose(jks)
    CkPfx::ckDispose(pkcs12)


    ProcedureReturn
EndProcedure