Certificate Signing with CMS
Certificate signing with CMS is supported since API version 18.
Certificate encapsulation with CMS is supported since API version 22.
PKCS #7 is a standard syntax for storing signed or encrypted data. The extension of PKCS#7, which is CMS, supports the following data types: data, signed data, encapsulated data, signed and encapsulated data, digest data, and encrypted data. It is often used to protect data integrity and confidentiality.
Currently, only CMS signature data and encapsulated data are supported.
How to Develop
-
Import the cert module.
import { cert } from '@kit.DeviceCertificateKit'; -
Call cert.createCmsGenerator to create a cmsGenerator object.
-
Call cmsGenerator.addSigner to add the signer information.
-
Call cmsGenerator.addCert to add a certificate.
-
Call cmsGenerator.doFinal to obtain the final signed data of the CMS.
- Example (using asynchronous APIs):
import { cert } from '@kit.DeviceCertificateKit';
import { BusinessError } from '@kit.BasicServicesKit';
let certData = '-----BEGIN CERTIFICATE-----\n' +
'MIICXjCCAcegAwIBAgIGAXKnJjrAMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNVBAYT\n' +
'AkNOMQwwCgYDVQQIDANzaGExDTALBgNVBAcMBHhpYW4xDTALBgNVBAoMBHRlc3Qx\n' +
'DTALBgNVBAMMBHRlc3QwHhcNMjQxMTIyMDkwNTIyWhcNMzQxMTIwMDkwNTIyWjBI\n' +
'MQswCQYDVQQGEwJDTjEMMAoGA1UECAwDc2hhMQ0wCwYDVQQHDAR4aWFuMQ0wCwYD\n' +
'VQQKDAR0ZXN0MQ0wCwYDVQQDDAR0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n' +
'iQKBgQC6nCZTM16Rk2c4P/hwfVm++jqe6GCA/PXXGe4YL218q1dTKMHBGEw8kXi0\n' +
'XLDcyyC2yUn8ywN2QSyly6ke9EE6PGfZywStLp4g2PTTWB04sS3aXT2y+fToiTXQ\n' +
'3AxfFYRpB+EgSdSCkJs6jKXVwbzu54kEtQTfs8UdBQ9nVKaJLwIDAQABo1MwUTAd\n' +
'BgNVHQ4EFgQU6QXnt1smb2HRSO/2zuRQnz/SDxowHwYDVR0jBBgwFoAU6QXnt1sm\n' +
'b2HRSO/2zuRQnz/SDxowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB\n' +
'gQBPR/+5xzFG1XlTdgwWVvqVxvhGUkbMTGW0IviJ+jbKsi57vnVsOtFzEA6y+bYx\n' +
'xG/kEOcwLtzeVHOQA+ZU5SVcc+qc0dfFiWjL2PSAG4bpqSTjujpuUk+g8ugixbG1\n' +
'a26pkDJhNeB/E3eBIbeydSY0A/dIGb6vbGo6BSq2KvnWAA==\n' +
'-----END CERTIFICATE-----\n';
let rsaStr1024: string =
'-----BEGIN RSA PRIVATE KEY-----\n' +
'Proc-Type: 4,ENCRYPTED\n' +
'DEK-Info: DES-EDE3-CBC,DB0AC6E3BEE16420\n\n' +
'1N5xykdckthZnswMV7blxXm2RCqe/OByBfMwFI7JoXR8STtMiStd4xA3W405k1Ma\n' +
'ExpsHgWwZaS23x+sQ1sL1dsqIPMrw1Vr+KrL20vQcCVjXPpGKauafVbtcWQ1r2PZ\n' +
'QJ4KWP6FhUp+sGt2ItODW3dK+1GdqL22ZtANrgFzS42Wh8FSn0UMCf6RG62DK62J\n' +
'z2jtf4XaorrGSjdTeY+fyyGfSyKidIMMBe+IXwlhCgAe7aHSaqXtMsv+BibB7PJ3\n' +
'XmEp1D/0ptL3r46txyYcuy8jSNCkW8er93KKnlRN6KbuYZPvPNncWkzZBzV17t5d\n' +
'QgtvVh32AKgqk5jm8YVnspOFiPrbrK9UN3IW15juFkfnhriM3IrKap4/kW+tfawZ\n' +
'DmHkSyl8xqFK413Rv0UvYBTjOcGbs2BSJYEvp8CIjtA17SvLmNw70K2nXWuQYutY\n' +
'+HyucPtHfEqUPQRzWTAMMntTru77u7dxo2WMMMxOtMJO5h7MAnZH9bAFiuO3ewcY\n' +
'eEePg10d8Owcfh9G6kc0HIGT9MMLMi0mTXhpoQTuWPYuSx6uUZL1fsp1x2fuM0qn\n' +
'bdf3+UnATYUu4tgvBHrMV7405Y6Y3PnqOFxVMeAHeOTo6UThtJ10mfeCPXGcUaHo\n' +
'P5enw7h4145cha3+S4hNrUwj3skrtavld7tY74p4DvgZSlCMF3JAm3DhpnEMVcYP\n' +
'Y6TkSevvxOpBvEHE41Y4VBCBwd9clcixI6cSBJKPUU4A/sc/kkNdGFcbzLQCg/zR\n' +
'1m7YmBROb2qy4w3lv/uwVnPGLg/YV465irRaN3hgz7/1lm8STKQhmQ==\n' +
'-----END RSA PRIVATE KEY-----\n';
// Convert the string into a Uint8Array.
function stringToUint8Array(str: string): Uint8Array {
let arr: number[] = [];
for (let i = 0, j = str.length; i < j; i++) {
arr.push(str.charCodeAt(i));
}
return new Uint8Array(arr);
}
async function testPkcs7SignByPromise() {
let certEncodingBlob: cert.EncodingBlob = {
data: stringToUint8Array(certData),
// Assign a value based on the encodingData format. FORMAT_PEM and FORMAT_DER are supported.
encodingFormat: cert.EncodingFormat.FORMAT_PEM
};
cert.createX509Cert(certEncodingBlob, (error, x509Cert) => {
if (error) {
console.error(`createX509Cert failed: errCode: ${error.code}, message: ${error.message}`);
} else {
try {
let cmsContentType = cert.CmsContentType.SIGNED_DATA;
let cmsGenerator = cert.createCmsGenerator(cmsContentType);
console.info('testPkcs7SignByPromise createCmsGenerator result: success.');
let privateKeyInfo: cert.PrivateKeyInfo = {
key: rsaStr1024,
password: '123456'
};
// If addCert is true, an error will be reported if the same certificate is added to addSigner or addCert.
let config: cert.CmsSignerConfig = {
mdName: 'SHA256',
addCert: false,
addAttr: true,
addSmimeCapAttr: true
}
cmsGenerator.addSigner(x509Cert, privateKeyInfo, config);
console.info('testPkcs7SignByPromise addSigner result: success.');
cmsGenerator.addCert(x509Cert);
console.info('testPkcs7SignByPromise addCert result: success.');
let content = new Uint8Array([1, 2, 3, 4]);
let optionsFinal: cert.CmsGeneratorOptions = {
contentDataFormat: cert.CmsContentDataFormat.BINARY,
outFormat: cert.CmsFormat.PEM,
isDetached: true
};
cmsGenerator.doFinal(content, optionsFinal).then(result => {
console.info('testPkcs7SignByPromise doFinal result: success, result = %s', result);
}).catch((error: BusinessError) => {
console.error(`testPkcs7SignByPromise failed: errCode: ${error.code}, message: ${error.message}`);
});
} catch (err) {
let e: BusinessError = err as BusinessError;
console.error(`testPkcs7SignByPromise failed: errCode: ${e.code}, message: ${e.message}`);
}
}
});
}
- Example (using synchronous APIs):
import { cert } from '@kit.DeviceCertificateKit';
import { BusinessError } from '@kit.BasicServicesKit';
let certData = '-----BEGIN CERTIFICATE-----\n' +
'MIICXjCCAcegAwIBAgIGAXKnJjrAMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNVBAYT\n' +
'AkNOMQwwCgYDVQQIDANzaGExDTALBgNVBAcMBHhpYW4xDTALBgNVBAoMBHRlc3Qx\n' +
'DTALBgNVBAMMBHRlc3QwHhcNMjQxMTIyMDkwNTIyWhcNMzQxMTIwMDkwNTIyWjBI\n' +
'MQswCQYDVQQGEwJDTjEMMAoGA1UECAwDc2hhMQ0wCwYDVQQHDAR4aWFuMQ0wCwYD\n' +
'VQQKDAR0ZXN0MQ0wCwYDVQQDDAR0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n' +
'iQKBgQC6nCZTM16Rk2c4P/hwfVm++jqe6GCA/PXXGe4YL218q1dTKMHBGEw8kXi0\n' +
'XLDcyyC2yUn8ywN2QSyly6ke9EE6PGfZywStLp4g2PTTWB04sS3aXT2y+fToiTXQ\n' +
'3AxfFYRpB+EgSdSCkJs6jKXVwbzu54kEtQTfs8UdBQ9nVKaJLwIDAQABo1MwUTAd\n' +
'BgNVHQ4EFgQU6QXnt1smb2HRSO/2zuRQnz/SDxowHwYDVR0jBBgwFoAU6QXnt1sm\n' +
'b2HRSO/2zuRQnz/SDxowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB\n' +
'gQBPR/+5xzFG1XlTdgwWVvqVxvhGUkbMTGW0IviJ+jbKsi57vnVsOtFzEA6y+bYx\n' +
'xG/kEOcwLtzeVHOQA+ZU5SVcc+qc0dfFiWjL2PSAG4bpqSTjujpuUk+g8ugixbG1\n' +
'a26pkDJhNeB/E3eBIbeydSY0A/dIGb6vbGo6BSq2KvnWAA==\n' +
'-----END CERTIFICATE-----\n';
let rsaStr1024: string =
'-----BEGIN RSA PRIVATE KEY-----\n' +
'Proc-Type: 4,ENCRYPTED\n' +
'DEK-Info: DES-EDE3-CBC,DB0AC6E3BEE16420\n\n' +
'1N5xykdckthZnswMV7blxXm2RCqe/OByBfMwFI7JoXR8STtMiStd4xA3W405k1Ma\n' +
'ExpsHgWwZaS23x+sQ1sL1dsqIPMrw1Vr+KrL20vQcCVjXPpGKauafVbtcWQ1r2PZ\n' +
'QJ4KWP6FhUp+sGt2ItODW3dK+1GdqL22ZtANrgFzS42Wh8FSn0UMCf6RG62DK62J\n' +
'z2jtf4XaorrGSjdTeY+fyyGfSyKidIMMBe+IXwlhCgAe7aHSaqXtMsv+BibB7PJ3\n' +
'XmEp1D/0ptL3r46txyYcuy8jSNCkW8er93KKnlRN6KbuYZPvPNncWkzZBzV17t5d\n' +
'QgtvVh32AKgqk5jm8YVnspOFiPrbrK9UN3IW15juFkfnhriM3IrKap4/kW+tfawZ\n' +
'DmHkSyl8xqFK413Rv0UvYBTjOcGbs2BSJYEvp8CIjtA17SvLmNw70K2nXWuQYutY\n' +
'+HyucPtHfEqUPQRzWTAMMntTru77u7dxo2WMMMxOtMJO5h7MAnZH9bAFiuO3ewcY\n' +
'eEePg10d8Owcfh9G6kc0HIGT9MMLMi0mTXhpoQTuWPYuSx6uUZL1fsp1x2fuM0qn\n' +
'bdf3+UnATYUu4tgvBHrMV7405Y6Y3PnqOFxVMeAHeOTo6UThtJ10mfeCPXGcUaHo\n' +
'P5enw7h4145cha3+S4hNrUwj3skrtavld7tY74p4DvgZSlCMF3JAm3DhpnEMVcYP\n' +
'Y6TkSevvxOpBvEHE41Y4VBCBwd9clcixI6cSBJKPUU4A/sc/kkNdGFcbzLQCg/zR\n' +
'1m7YmBROb2qy4w3lv/uwVnPGLg/YV465irRaN3hgz7/1lm8STKQhmQ==\n' +
'-----END RSA PRIVATE KEY-----\n';
// Convert the string into a Uint8Array.
function stringToUint8Array(str: string): Uint8Array {
let arr: number[] = [];
for (let i = 0, j = str.length; i < j; i++) {
arr.push(str.charCodeAt(i));
}
return new Uint8Array(arr);
}
function testPkcs7SignBySync() {
let certEncodingBlob: cert.EncodingBlob = {
data: stringToUint8Array(certData),
// Assign a value based on the encodingData format. FORMAT_PEM and FORMAT_DER are supported.
encodingFormat: cert.EncodingFormat.FORMAT_PEM
};
cert.createX509Cert(certEncodingBlob, (error, x509Cert) => {
if (error) {
console.error(`createX509Cert failed: errCode: ${error.code}, message: ${error.message}`);
} else {
try {
let cmsContentType = cert.CmsContentType.SIGNED_DATA;
let cmsGenerator = cert.createCmsGenerator(cmsContentType);
console.info('testPkcs7SignBySync createCmsGenerator success.');
let privateKeyInfo: cert.PrivateKeyInfo = {
key: rsaStr1024,
password: '123456'
};
// If addCert is true, an error will be reported if the same certificate is added to addSigner or addCert.
let config: cert.CmsSignerConfig = {
mdName:'SHA256',
addCert:false,
addAttr:false,
addSmimeCapAttr:false
}
cmsGenerator.addSigner(x509Cert, privateKeyInfo, config);
console.info('testPkcs7SignBySync addSigner result: success.');
cmsGenerator.addCert(x509Cert);
console.info('testPkcs7SignBySync addCert result: success.');
let content = new Uint8Array([1,2,3,4]);
let optionsFinal: cert.CmsGeneratorOptions = {
contentDataFormat : cert.CmsContentDataFormat.BINARY,
outFormat : cert.CmsFormat.DER,
isDetached : false
};
let output = cmsGenerator.doFinalSync(content, optionsFinal);
console.info('testPkcs7SignBySync doFinalSync result: success, output = %s.', output);
} catch (err) {
let e: BusinessError = err as BusinessError;
console.error(`testPkcs7SignBySync failed: errCode: ${e.code}, message: ${e.message}`);
}
}
});
}