DEV Community

HarmonyOS
HarmonyOS

Posted on

How to parse the p12 certificate?

Read the original article:How to parse the p12 certificate?

Problem Description

How to parse the p12 certificate?

Background Knowledge

  • The composition of multi-level certificates:

    • Root certificate: The root certificate is the most authoritative and confidential certificate in the certificate chain. It is usually stored offline to ensure its security. The root certificate is used to sign one or more intermediate certificates.
    • Intermediate certificates: Intermediate certificates are signed by the root certificate and can further sign other intermediate certificates or end-user certificates. The existence of intermediate certificates increases the flexibility and security of
    • certificate management. If the intermediate certificate is accidentally lost or leaked, a new intermediate certificate can be reissued without affecting the security of the root certificate or other certificates.
    • End-user certificate: The end-user certificate is the last link in the certificate chain and is used to verify the identity of the end user. It is usually signed by an intermediate certificate and contains the user's public key information and other relevant information.
  • cert.createTrustAnchorsWithKeyStore reads the CA certificate from the P12 file to construct an array of TrustAnchor objects.

  createTrustAnchorsWithKeyStore(keystore: <span>Uint8Array</span>, pwd: string): Promise<<span>Array</span><X509TrustAnchor>>
Enter fullscreen mode Exit fullscreen mode
  • cert.parsePkcs12 means parsing the certificate, private key and other certificate collections from the P12 file and returning the result.
  parsePkcs12(data: <span>Uint8Array</span>, config: Pkcs12ParsingConfig): Pkcs12Data
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Process

  • Check Available APIs: Review HarmonyOS’s security and crypto modules to confirm lack of native PKCS#12 support.
  • Evaluate Third-Party Libraries: Consider using well-established cryptographic libraries which is widely used for PKCS#12 operations.
  • Manage Security and Performance: Test the parsing process for correctness, error handling (e.g., wrong password), and resource usage.

Solution

  • createTrustAnchorsWithKeyStore parses multi-level certificates:
  let filePath =  getContext().filesDir+"/client_have_ca_123456.p12";
  let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE);

  fs.stat(filePath).then((stat: fs.Stat) => {
    let buf = new ArrayBuffer(stat.size);
    fs.readSync(file.fd, buf);
    fs.closeSync(file);
    console.info("get file info succeed, the size of file is " + stat.size);

    try {
      cert.createTrustAnchorsWithKeyStore(new Uint8Array(buf),'123456').then((data) => {
        console.log(`createTrustAnchorsWithKeyStore sucess, number of the result is: ${data.length}`);
      }).catch((err : BusinessError) => {
        console.error(`createTrustAnchorsWithKeyStore failed:${err}`);
      })
    } catch (error) {
      console.error(`createTrustAnchorsWithKeyStore failed:${err}`);
    }

  }).catch((err: BusinessError) => {
    console.error("get file info failed with error message: " + err.message + ", error code: " + err.code);
  });
Enter fullscreen mode Exit fullscreen mode
  • parsePkcs12 parses a single certificate:
  let filePath =  getContext().filesDir+"/client_have_ca_123456.p12";
  let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE);

  fs.stat(filePath).then((stat: fs.Stat) => {
    let buf = new ArrayBuffer(stat.size);
    fs.readSync(file.fd, buf);
    fs.closeSync(file);
    console.info("get file info succeed, the size of file is " + stat.size);

    let conf: cert.Pkcs12ParsingConfig = {
      password: "123456",
      needsCert: false,
      needsPrivateKey: true,
      privateKeyFormat: cert.EncodingBaseFormat.DER,
      needsOtherCerts: false,
    };
    let p12: cert.Pkcs12Data = cert.parsePkcs12(new Uint8Array(buf), conf);
    console.info("parsePKCS12 succeed.");
    if (p12.privateKey) {
      console.info("privateKey:" + p12.privateKey.toString())
    }

  }).catch((err: BusinessError) => {
    console.error("get file info failed with error message: " + err.message + ", error code: " + err.code);
  });
Enter fullscreen mode Exit fullscreen mode

Written by Mucahid Kincir

Top comments (0)