diff --git a/zh-cn/application-dev/security/cert-guidelines.md b/zh-cn/application-dev/security/cert-guidelines.md index 81d3592b45396a7d66e12e90a0c6effe985b15b2..27f36aa7d810b1abae300668338657dba8d7191f 100755 --- a/zh-cn/application-dev/security/cert-guidelines.md +++ b/zh-cn/application-dev/security/cert-guidelines.md @@ -2,7 +2,7 @@ > **说明** > -> 本开发指导需使用API version 9及以上版本SDK,仅适用于JS语言开发。 +> 本开发指导需使用API version 9及以上版本SDK。 ## 使用证书操作 @@ -53,107 +53,94 @@ 示例:解析X509证书数据生成证书对象,并调用对象方法(包含场景1-6) -```javascript -import cryptoCert from '@ohos.security.cert'; -import cryptoFramework from '@ohos.security.cryptoFramework'; +```ts +import certFramework from '@ohos.security.cert'; +import { BusinessError } from '@ohos.base'; + +// Certificate data, which is only an example. The certificate data varies with the service. +let certData = '-----BEGIN CERTIFICATE-----\n' + + 'MIIBLzCB1QIUO/QDVJwZLIpeJyPjyTvE43xvE5cwCgYIKoZIzj0EAwIwGjEYMBYG\n' + + 'A1UEAwwPRXhhbXBsZSBSb290IENBMB4XDTIzMDkwNDExMjAxOVoXDTI2MDUzMDEx\n' + + 'MjAxOVowGjEYMBYGA1UEAwwPRXhhbXBsZSBSb290IENBMFkwEwYHKoZIzj0CAQYI\n' + + 'KoZIzj0DAQcDQgAEHjG74yMIueO7z3T+dyuEIrhxTg2fqgeNB3SGfsIXlsiUfLTa\n' + + 'tUsU0i/sePnrKglj2H8Abbx9PK0tsW/VgqwDIDAKBggqhkjOPQQDAgNJADBGAiEA\n' + + '0ce/fvA4tckNZeB865aOApKXKlBjiRlaiuq5mEEqvNACIQDPD9WyC21MXqPBuRUf\n' + + 'BetUokslUfjT6+s/X4ByaxycAA==\n' + + '-----END CERTIFICATE-----\n'; + +// Convert the certificate data form a string to a Uint8Array. +function stringToUint8Array(str: string): Uint8Array { + let arr: Array = []; + for (let i = 0, j = str.length; i < j; i++) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); +} + +// Certificate example +function certSample(): void { + let encodingBlob: certFramework.EncodingBlob = { + // Convert the certificate data string to a Uint8Array. + data: stringToUint8Array(certData), + // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format. + encodingFormat: certFramework.EncodingFormat.FORMAT_PEM + }; -// 证书数据,此处仅示例,业务需根据场景自行设置 -let certData = "-----BEGIN CERTIFICATE-----\n" -+ "MIID/jCCAuagAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCQ04x\n" -+ "ETAPBgNVBAgMCHNoYW5naGFpMQ8wDQYDVQQHDAZodWF3ZWkxFTATBgNVBAoMDHd3\n" -+ "dy50ZXN0LmNvbTENMAsGA1UECwwEdGVzdDEVMBMGA1UEAwwMd3d3LnRlc3QuY29t\n" -+ "MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tMB4XDTIyMDgyOTA2NTUwM1oX\n" -+ "DTIzMDgyOTA2NTUwM1owezELMAkGA1UEBhMCQ04xETAPBgNVBAgMCHNoYW5naGFp\n" -+ "MRUwEwYDVQQKDAx3d3cudGVzdC5jb20xDTALBgNVBAsMBHRlc3QxFTATBgNVBAMM\n" -+ "DHd3dy50ZXN0LmNvbTEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIw\n" -+ "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJmY9T4SzXXwKvfMvnvMWY7TqUJK\n" -+ "jnWf2Puv0YUQ2fdvyoKQ2LQXdtzoUL53j587oI+IXelOr7dg020zPyun0cmZHZ4y\n" -+ "l/qAcrWbDjZeEGcbbb5UtQtn1WOEnv8pkXluO355mbZQUKK9L3gFWseXJKGbIXw0\n" -+ "NRpaJZzqvPor4m3a5pmJKPHOlivUdYfLaKSkNj3DlaFzCWKV82k5ee6gzVyETtG+\n" -+ "XN+vq8qLybT+fIFsLNMmAHzRxlqz3NiH7yh+1/p/Knvf8bkkRVR2btH51RyX2RSu\n" -+ "DjPM0/VRL8fxDSDeWBq+Gvn/E6AbOVMmkx63tcyWHhklCSaZtyz7kq39TQMCAwEA\n" -+ "AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0\n" -+ "ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFFiFDysfADQCzRZCOSPupQxFicwzMB8G\n" -+ "A1UdIwQYMBaAFNYQRQiPsG8HefOTsmsVhaVjY7IPMA0GCSqGSIb3DQEBCwUAA4IB\n" -+ "AQAeppxf6sKQJxJQXKPTT3xHKaskidNwDBbOSIvnVvWXicZXDs+1sF6tUaRgvPxL\n" -+ "OL58+P2Jy0tfSwj2WhqQRGe9MvQ5iFHcdelZc0ciW6EQ0VDHIaDAQc2nQzej/79w\n" -+ "UE7BJJV3b9n1be2iCsuodKO14pOkMb84WcIxng+8SD+MiFqV5BPO1QyKGdO1PE1b\n" -+ "+evjyTpFSTgZf2Mw3fGtu5hfEXyHw1lnsFY2MlSwiRlAym/gm4aXy+4H6LyXKd56\n" -+ "UYQ6fituD0ziaw3RI6liyIe7aENHCkZf6bAvMRhk4QiU4xu6emwX8Qt1bT7RthP0\n" -+ "1Vsro0IOeXT9WAcqEtQUegsi\n" -+ "-----END CERTIFICATE-----\n"; - -// string转Uint8Array -function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; i++) { - arr.push(str.charCodeAt(i)); + // Create an X509Cert instance. + certFramework.createX509Cert(encodingBlob, (err, x509Cert) => { + if (err != null) { + // Failed to create the X509Cert instance. + console.error('createX509Cert failed, errCode: ' + err.code + ', errMsg: ' + err.message); + return; } - return new Uint8Array(arr); -} + // The X509Cert instance is successfully created. + console.log('createX509Cert success'); + + // Obtain the certificate version. + let version = x509Cert.getVersion(); + + // Obtain the serialized data of the certificate. + x509Cert.getEncoded((err, data) => { + if (err != null) { + // Failed to obtain the serialized data of the certificate. + console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message); + } else { + // The serialized data of the certificate is successfully obtained. + console.log('getEncoded success'); + } + }); -// 证书示例 -function certSample() { - let encodingBlob = { - // 将string类型证书数据转为Uint8Array - data: stringToUint8Array(certData), - // 证书格式:支持PEM和DER,此例中对应PEM - encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM - }; + // Obtain the public key object using the getPublicKey() of the upper-level certificate object or this (self-signed) certificate object. + try { + let pubKey = x509Cert.getPublicKey(); - // 创建证书对象 - cryptoCert.createX509Cert(encodingBlob, function (err, x509Cert) { - if (err != null) { - // 创建证书对象失败 - console.log("createX509Cert failed, errCode: " + err.code + ", errMsg: " + err.message); - return; + // Verify the certificate signature. + x509Cert.verify(pubKey, (err, data) => { + if (err == null) { + // The signature verification is successful. + console.log('verify success'); + } else { + // The signature verification failed. + console.error('verify failed, errCode: ' + err.code + ', errMsg: ' + err.message); } - // 创建证书对象成功 - console.log("createX509Cert success"); - - // 获取证书版本 - let version = x509Cert.getVersion(); - - // 获取证书对象的序列化数据 - x509Cert.getEncoded(function (err, data) { - if (err != null) { - // 获取序列化数据失败 - console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message); - } else { - // 获取序列化数据成功 - console.log("getEncoded success"); - } - }); + }); + } catch (error) { + let e: BusinessError = error as BusinessError; + console.error('getPublicKey failed, errCode: ' + e.code + ', errMsg: ' + e.message); + } - // 业务需通过上级证书对象或本证书对象(自签名)的getPublicKey接口获取公钥对象,此处省略 - let pubKey = null; - try { - pubKey = x509Cert.getPublicKey(); - } catch (error) { - console.log("getPublicKey failed, errCode: " + error.code + ", errMsg: " + error.message); - } - // 证书验签 - x509Cert.verify(pubKey, function (err, data) { - if (err == null) { - // 验签成功 - console.log("verify success"); - } else { - // 验签失败 - console.log("verify failed, errCode: " + err.code + ", errMsg: " + err.message); - } - }); + // Time represented in a string. + let date = '20230930000001Z'; - // 时间字符串 - let date = "20220830000001Z"; - - // 校验证书有效期 - try { - x509Cert.checkValidityWithDate(date); - } catch (error) { - console.log("checkValidityWithDate failed, errCode: " + error.code + ", errMsg: " + error.message); - } - }); + // Verify the certificate validity period. + try { + x509Cert.checkValidityWithDate(date); + } catch (error) { + let e: BusinessError = error as BusinessError; + console.error('checkValidityWithDate failed, errCode: ' + e.code + ', errMsg: ' + e.message); + } + }); } ``` @@ -161,7 +148,7 @@ function certSample() { > **说明** > -> 本场景基于API version 10,OH SDK版本4.0.9及以上,适用于JS语言开发 +> 本场景基于API version 10,OH SDK版本4.0.9及以上。 **场景说明** @@ -190,67 +177,70 @@ function certSample() { 示例:解析X509证书扩展域段数据生成证书扩展域段对象,并调用对象方法(包含场景1-3) -```javascript -import cryptoCert from '@ohos.security.cert'; +```ts +import certFramework from '@ohos.security.cert'; +import { BusinessError } from '@ohos.base'; -// 证书扩展域段数据,此处仅示例,业务需根据场景自行设置 -let certData = new Uint8Array([ - 0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, +// Certificate extension data, which is only an example. Set it based on service requirements. +let extData = new Uint8Array([ + 0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, - 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, - 0x02, 0x01, 0xC6, 0x30, 0x1D, 0x06, 0x03, 0x55, + 0x02, 0x01, 0xC6, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xE0, 0x8C, - 0x9B, 0xDB, 0x25, 0x49, 0xB3, 0xF1, 0x7C, 0x86, + 0x9B, 0xDB, 0x25, 0x49, 0xB3, 0xF1, 0x7C, 0x86, 0xD6, 0xB2, 0x42, 0x87, 0x0B, 0xD0, 0x6B, 0xA0, 0xD9, 0xE4 ]); -// string转Uint8Array -function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; i++) { +// Convert the string into a Uint8Array. +function stringToUint8Array(str: string): Uint8Array { + let arr: Array = []; + for (let i = 0, j = str.length; i < j; i++) { arr.push(str.charCodeAt(i)); } return new Uint8Array(arr); } -// 证书扩展域段示例 -function certExtensionSample() { - let encodingBlob = { - data: certData, - // 证书扩展域段格式:当前仅支持DER格式 - encodingFormat: cryptoCert.EncodingFormat.FORMAT_DER +// Certificate extension example. +function certExtensionSample(): void { + let encodingBlob: certFramework.EncodingBlob = { + data: extData, + // Certificate extension format. Currently, only the DER format is supported. + encodingFormat: certFramework.EncodingFormat.FORMAT_DER }; - // 创建证书扩展域段对象 - cryptoCert.createCertExtension(encodingBlob, function (err, certExtension) { + // Create a CerExtension instance. + certFramework.createCertExtension(encodingBlob, (err, certExtension) => { if (err != null) { - // 创建证书扩展域段对象失败 - console.log("createCertExtension failed, errCode: " + err.code + ", errMsg: " + err.message); + // The CerExtension instance fails to be created. + console.error('createCertExtension failed, errCode: ' + err.code + ', errMsg: ' + err.message); return; } - // 创建证书扩展域段对象成功 - console.log("createCertExtension success"); - + // A CerExtension instance is created. + console.log('createCertExtension success'); + try { - // 获取证书扩展域段对象的序列化数据 + // Obtain the serialized data of the CerExtension instance. let encodedData = certExtension.getEncoded(); - - // 获取证书扩展域段对象的对象标识符列表 - let oidList = certExtension.getOidList(cryptoCert.ExtensionOidType.EXTENSION_OID_TYPE_ALL); - - // 根据对象标识符获取证书扩展域段信息 - let oidData = "2.5.29.14"; - let oid = { + + // Obtain the OIDs of the certificate extensions. + let oidList = certExtension.getOidList(certFramework.ExtensionOidType.EXTENSION_OID_TYPE_ALL); + + // Obtain the certificate extension information based on a OID. + let oidData = '2.5.29.14'; + let oid: certFramework.DataBlob = { data: stringToUint8Array(oidData), } - let entry = certExtension.getEntry(cryptoCert.ExtensionEntryType.EXTENSION_ENTRY_TYPE_ENTRY, oid); - - // 校验证书是否为CA证书 + let entry = certExtension.getEntry(certFramework.ExtensionEntryType.EXTENSION_ENTRY_TYPE_ENTRY, oid); + + // Check whether the certificate is a CA certificate. let pathLen = certExtension.checkCA(); + console.log('test cert extension success'); } catch (err) { - console.log("operation failed: " + JSON.stringify(err)); + let e: BusinessError = err as BusinessError; + console.error('operation failed, message: ' + e.message + ' code: ' + e.code); } }); } @@ -303,98 +293,194 @@ function certExtensionSample() { 示例:解析X509证书吊销列表数据生成证书吊销列表对象,并调用对象方法(包含场景1-6) -```javascript -import cryptoCert from '@ohos.security.cert'; +```ts +import certFramework from '@ohos.security.cert'; import cryptoFramework from '@ohos.security.cryptoFramework'; +import { BusinessError } from '@ohos.base'; + +// CRL data, which is only an example. The CRL data varies with the service. +let crlData = '-----BEGIN X509 CRL-----\n' + + 'MIHzMF4CAQMwDQYJKoZIhvcNAQEEBQAwFTETMBEGA1UEAxMKQ1JMIGlzc3VlchcN\n' + + 'MTcwODA3MTExOTU1WhcNMzIxMjE0MDA1MzIwWjAVMBMCAgPoFw0zMjEyMTQwMDUz\n' + + 'MjBaMA0GCSqGSIb3DQEBBAUAA4GBACEPHhlaCTWA42ykeaOyR0SGQIHIOUR3gcDH\n' + + 'J1LaNwiL+gDxI9rMQmlhsUGJmPIPdRs9uYyI+f854lsWYisD2PUEpn3DbEvzwYeQ\n' + + '5SqQoPDoM+YfZZa23hoTLsu52toXobP74sf/9K501p/+8hm4ROMLBoRT86GQKY6g\n' + + 'eavsH0Q3\n' + + '-----END X509 CRL-----\n' + + +let certData = '-----BEGIN CERTIFICATE-----\n' + + 'MIIBLzCB1QIUO/QDVJwZLIpeJyPjyTvE43xvE5cwCgYIKoZIzj0EAwIwGjEYMBYG\n' + + 'A1UEAwwPRXhhbXBsZSBSb290IENBMB4XDTIzMDkwNDExMjAxOVoXDTI2MDUzMDEx\n' + + 'MjAxOVowGjEYMBYGA1UEAwwPRXhhbXBsZSBSb290IENBMFkwEwYHKoZIzj0CAQYI\n' + + 'KoZIzj0DAQcDQgAEHjG74yMIueO7z3T+dyuEIrhxTg2fqgeNB3SGfsIXlsiUfLTa\n' + + 'tUsU0i/sePnrKglj2H8Abbx9PK0tsW/VgqwDIDAKBggqhkjOPQQDAgNJADBGAiEA\n' + + '0ce/fvA4tckNZeB865aOApKXKlBjiRlaiuq5mEEqvNACIQDPD9WyC21MXqPBuRUf\n' + + 'BetUokslUfjT6+s/X4ByaxycAA==\n' + + '-----END CERTIFICATE-----\n'; + +let pubKeyData = new Uint8Array([ + 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xDC, 0x4C, 0x2D, + 0x57, 0x49, 0x3D, 0x42, 0x52, 0x1A, 0x09, 0xED, 0x3E, 0x90, 0x29, 0x51, 0xF7, 0x70, 0x15, 0xFE, + 0x76, 0xB0, 0xDB, 0xDF, 0xA1, 0x2C, 0x6C, 0x67, 0x95, 0xDA, 0x63, 0x3D, 0x4F, 0x71, 0x48, 0x8C, + 0x3E, 0xFA, 0x24, 0x79, 0xE9, 0xF2, 0xF2, 0x20, 0xCB, 0xF1, 0x59, 0x6B, 0xED, 0xC8, 0x72, 0x66, + 0x6E, 0x31, 0xD4, 0xF3, 0xCE, 0x0B, 0x12, 0xC4, 0x17, 0x39, 0xB4, 0x52, 0x16, 0xD3, 0xE3, 0xC0, + 0xF8, 0x48, 0xB3, 0xF6, 0x40, 0xD5, 0x47, 0x23, 0x30, 0x7F, 0xA7, 0xC5, 0x5A, 0x5A, 0xBB, 0x5C, + 0x7B, 0xEF, 0x69, 0xE2, 0x74, 0x35, 0x24, 0x22, 0x25, 0x45, 0x7E, 0xFC, 0xE8, 0xC4, 0x52, 0x65, + 0xA0, 0x4E, 0xBC, 0xFD, 0x3F, 0xD9, 0x85, 0x14, 0x8A, 0x5A, 0x93, 0x02, 0x24, 0x6C, 0x19, 0xBA, + 0x81, 0xBE, 0x65, 0x2E, 0xCB, 0xBB, 0xE9, 0x91, 0x7B, 0x7C, 0x47, 0xC2, 0x61, 0x02, 0x03, 0x01, + 0x00, 0x01 +]); -// 证书吊销列表数据,此处仅示例,业务需根据场景自行设置 -let crlData = "-----BEGIN X509 CRL-----\n" -+ "MIIBijB0AgEBMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHJvb3QtY2ExFw0y\n" -+ "MDA2MTkxNjE1NDhaFw0yMDA3MTkxNjE1NDhaMBwwGgIJAMsozRATnap1Fw0yMDA2\n" -+ "MTkxNjEyMDdaoA8wDTALBgNVHRQEBAICEAIwDQYJKoZIhvcNAQELBQADggEBACPs\n" -+ "9gQB+djaXPHHRmAItebZpD3iJ/e36Dxr6aMVkn9FkI8OVpUI4RNcCrywyCZHQJte\n" -+ "995bbPjP7f1sZstOTZS0fDPgJ5SPAxkKOQB+SQnBFrlZSsxoUNU60gRqd2imR0Rn\n" -+ "1r09rP69F6E4yPc9biEld+llLGgoImP3zPOVDD6fbfcvVkjStY3bssVEQ/vjp4a3\n" -+ "/I12U7ZnSe3jaKqaQBoVJppkTFOIOq7IOxf5/IkMPmvRHDeC2IzDMzcUxym0dkny\n" -+ "EowHrjzo0bZVqpHMA2YgKZuwTpVLHk9GeBEK2hVkIoPVISkmiU4HFg0S6z68C5yd\n" -+ "DrAA7hErVgXhtURLbAI=\n" -+ "-----END X509 CRL-----\n"; - -// string转Uint8Array -function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; i++) { - arr.push(str.charCodeAt(i)); - } - return new Uint8Array(arr); +let priKeyData = new Uint8Array([ + 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x61, 0x30, 0x82, 0x02, 0x5D, 0x02, 0x01, + 0x00, 0x02, 0x81, 0x81, 0x00, 0xDC, 0x4C, 0x2D, 0x57, 0x49, 0x3D, 0x42, 0x52, 0x1A, 0x09, 0xED, + 0x3E, 0x90, 0x29, 0x51, 0xF7, 0x70, 0x15, 0xFE, 0x76, 0xB0, 0xDB, 0xDF, 0xA1, 0x2C, 0x6C, 0x67, + 0x95, 0xDA, 0x63, 0x3D, 0x4F, 0x71, 0x48, 0x8C, 0x3E, 0xFA, 0x24, 0x79, 0xE9, 0xF2, 0xF2, 0x20, + 0xCB, 0xF1, 0x59, 0x6B, 0xED, 0xC8, 0x72, 0x66, 0x6E, 0x31, 0xD4, 0xF3, 0xCE, 0x0B, 0x12, 0xC4, + 0x17, 0x39, 0xB4, 0x52, 0x16, 0xD3, 0xE3, 0xC0, 0xF8, 0x48, 0xB3, 0xF6, 0x40, 0xD5, 0x47, 0x23, + 0x30, 0x7F, 0xA7, 0xC5, 0x5A, 0x5A, 0xBB, 0x5C, 0x7B, 0xEF, 0x69, 0xE2, 0x74, 0x35, 0x24, 0x22, + 0x25, 0x45, 0x7E, 0xFC, 0xE8, 0xC4, 0x52, 0x65, 0xA0, 0x4E, 0xBC, 0xFD, 0x3F, 0xD9, 0x85, 0x14, + 0x8A, 0x5A, 0x93, 0x02, 0x24, 0x6C, 0x19, 0xBA, 0x81, 0xBE, 0x65, 0x2E, 0xCB, 0xBB, 0xE9, 0x91, + 0x7B, 0x7C, 0x47, 0xC2, 0x61, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x5A, 0xCF, 0x0F, + 0xF5, 0xA6, 0x1C, 0x19, 0x65, 0x8C, 0x94, 0x40, 0xF6, 0x84, 0x28, 0x74, 0x40, 0x42, 0x34, 0xDE, + 0xC3, 0x00, 0x5E, 0x72, 0x4D, 0x96, 0xE9, 0x4C, 0xBD, 0xC9, 0xDB, 0x14, 0x9F, 0xD5, 0xBB, 0xA9, + 0x0C, 0x20, 0xC2, 0xBE, 0x7A, 0x80, 0x89, 0xEC, 0x99, 0x04, 0xF0, 0xEE, 0x7B, 0x83, 0x20, 0x1D, + 0x37, 0x19, 0x55, 0x85, 0xF6, 0x8E, 0x3B, 0xFB, 0x16, 0xF3, 0xD3, 0x6F, 0xEE, 0x73, 0x12, 0x53, + 0xCA, 0x77, 0xD7, 0x6C, 0x29, 0xF5, 0x08, 0xA3, 0x09, 0x01, 0x0B, 0x00, 0x05, 0x57, 0xAD, 0x4D, + 0xF0, 0x92, 0xB2, 0x5A, 0x8B, 0x19, 0x09, 0x81, 0x86, 0xFE, 0x66, 0xB9, 0x33, 0x88, 0x28, 0xF3, + 0x37, 0x73, 0x09, 0x5F, 0xD7, 0xC9, 0xC6, 0xFA, 0x13, 0x74, 0xFE, 0xAE, 0x53, 0xA9, 0x71, 0x67, + 0xCE, 0x3A, 0xE6, 0x8D, 0x35, 0xD1, 0xB8, 0xFD, 0x6F, 0x0D, 0x43, 0xC2, 0xD1, 0x02, 0x41, 0x00, + 0xF7, 0x33, 0xE5, 0x6C, 0x29, 0x5A, 0x30, 0x58, 0xA4, 0x52, 0x65, 0xA0, 0x39, 0xC2, 0xE8, 0xAE, + 0x5F, 0xA3, 0x2D, 0x0C, 0x65, 0xB1, 0x7B, 0xFD, 0x92, 0xBF, 0x47, 0x87, 0x97, 0x40, 0xCB, 0x54, + 0xF9, 0xBB, 0x50, 0x27, 0x70, 0x51, 0xD0, 0xD8, 0x48, 0x0D, 0xC6, 0x47, 0x60, 0xF8, 0x4E, 0x0A, + 0x32, 0x76, 0x6D, 0xA4, 0xBA, 0x40, 0xE5, 0x58, 0xF8, 0x4A, 0x39, 0x4E, 0xF8, 0x3F, 0x4E, 0x2D, + 0x02, 0x41, 0x00, 0xE4, 0x23, 0x2A, 0x5F, 0x59, 0xCF, 0x7C, 0x91, 0x24, 0x0D, 0xA2, 0x44, 0x17, + 0xCD, 0x37, 0xDE, 0x1F, 0x53, 0x4D, 0x33, 0x9F, 0x90, 0x4D, 0xD9, 0x72, 0x64, 0x25, 0xBA, 0xAB, + 0x47, 0x91, 0xC4, 0x99, 0x95, 0x86, 0xB5, 0x8A, 0xEA, 0x77, 0xF7, 0x64, 0x72, 0x5E, 0xB7, 0xBB, + 0x16, 0xA1, 0x64, 0xA4, 0xE1, 0x2D, 0x76, 0x6D, 0xEF, 0xB1, 0x5E, 0xD6, 0x17, 0xE8, 0xAA, 0xB6, + 0xA0, 0xD9, 0x85, 0x02, 0x41, 0x00, 0xDF, 0xC8, 0x5B, 0x28, 0x4F, 0x47, 0x15, 0xFD, 0x28, 0xC4, + 0x6E, 0xBB, 0x5D, 0x8E, 0xD4, 0x95, 0x06, 0x7E, 0xF1, 0x89, 0x07, 0x86, 0x64, 0x78, 0x69, 0x20, + 0x3F, 0xE0, 0xBF, 0x4C, 0x28, 0xC6, 0x04, 0x4D, 0x4D, 0x82, 0x66, 0x6B, 0xAA, 0x64, 0x20, 0xD6, + 0x57, 0x68, 0xC6, 0xA0, 0x02, 0x05, 0xB9, 0x28, 0xFC, 0x98, 0xE3, 0x03, 0x5C, 0x9B, 0xEE, 0x29, + 0x43, 0x37, 0xFA, 0x03, 0x55, 0x01, 0x02, 0x40, 0x69, 0x5B, 0x7C, 0x24, 0x10, 0xDB, 0xEB, 0x91, + 0x33, 0xEF, 0x3F, 0xF2, 0xE6, 0x73, 0x15, 0xCB, 0xF4, 0xF7, 0x89, 0x7D, 0xBF, 0xC0, 0xEA, 0xD2, + 0xF3, 0x2B, 0x20, 0xE9, 0x76, 0x54, 0x55, 0x13, 0x50, 0x42, 0x67, 0xB5, 0xCB, 0x73, 0xC0, 0xF7, + 0x75, 0x62, 0x04, 0x30, 0x21, 0xAC, 0xAF, 0xD8, 0x44, 0xF4, 0xE1, 0x04, 0x02, 0x7D, 0x61, 0x92, + 0x84, 0x99, 0x02, 0x10, 0x64, 0xCB, 0x1F, 0xE9, 0x02, 0x41, 0x00, 0xAB, 0x4B, 0x7D, 0x90, 0x7C, + 0x57, 0x08, 0x6B, 0xC0, 0x43, 0x72, 0x09, 0x8A, 0x18, 0x35, 0x36, 0x64, 0x9D, 0x84, 0x8D, 0xF1, + 0x84, 0x94, 0x48, 0xC6, 0x80, 0x9D, 0xB9, 0xA2, 0x58, 0x0A, 0x4D, 0x0A, 0xCA, 0x1E, 0xD6, 0x05, + 0x55, 0x5B, 0xFE, 0xD7, 0xAA, 0x70, 0xED, 0x76, 0xB3, 0x40, 0x2E, 0xA0, 0xB3, 0x32, 0x37, 0xB0, + 0xA0, 0xB9, 0x96, 0x2D, 0xC4, 0x70, 0xE9, 0x99, 0x10, 0x67, 0x8D +]); + +// Convert the certificate data form a string to a Uint8Array. +function stringToUint8Array(str: string): Uint8Array { + let arr: Array = []; + for (let i = 0, j = str.length; i < j; i++) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); } -// 证书吊销列表示例 -function crlSample() { - let encodingBlob = { - // 将string类型证书吊销列表数据转为Uint8Array - data: stringToUint8Array(crlData), - // 证书吊销列表格式:支持PEM和DER,此例中对应PEM - encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM - }; +// Example of a CRL. +function crlSample(): void { + let encodingBlob: certFramework.EncodingBlob = { + // Convert the CRL data from a string to a Uint8Array. + data: stringToUint8Array(crlData), + // CRL format. Only PEM and DER are supported. In this example, the CRL is in PEM format. + encodingFormat: certFramework.EncodingFormat.FORMAT_PEM + }; - // 创建证书吊销列表对象 - cryptoCert.createX509Crl(encodingBlob, function (err, x509Crl) { - if (err != null) { - // 创建证书吊销列表对象失败 - console.log("createX509Crl failed, errCode: " + err.code + ", errMsg: " + err.message); - return; - } - // 创建证书吊销列表对象成功 - console.log("createX509Crl success"); - - // 获取证书吊销列表版本 - let version = x509Crl.getVersion(); - - // 获取证书吊销列表对象的序列化数据 - x509Crl.getEncoded(function (err, data) { - if (err != null) { - // 获取序列化数据失败 - console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message); - } else { - // 获取序列化数据成功 - console.log("getEncoded success"); - } - }); + // Create an X509Crl instance. + certFramework.createX509Crl(encodingBlob, (err, x509Crl) => { + if (err != null) { + // Failed to create the X509Crl instance. + console.error('createX509Crl failed, errCode: ' + err.code + ', errMsg: ' + err.message); + return; + } + // The X509Crl instance is successfully created. + console.log('createX509Crl success'); + + // Obtain the CRL version. + let version = x509Crl.getVersion(); + + // Obtain the serialized data of the CRL. + x509Crl.getEncoded((err, data) => { + if (err != null) { + // Failed to obtain the serialized data of the certificate. + console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message); + } else { + // The serialized data of the certificate is successfully obtained. + console.log('getEncoded success'); + } + }); - // 业务需通过cryptoFramework的createX509Cert生成X509Cert证书对象,此处省略 - let x509Cert = null; - // 检查证书是否被吊销 + // Create an X509Cert instance by using createX509Cert() of certFramework. + let certBlob: certFramework.EncodingBlob = { + data: stringToUint8Array(certData), + encodingFormat: certFramework.EncodingFormat.FORMAT_PEM + }; + certFramework.createX509Cert(certBlob, (err, cert) => { + if (err == null) { try { - let revokedFlag = x509Crl.isRevoked(x509Cert); + // Check whether the certificate is revoked. + let revokedFlag = x509Crl.isRevoked(cert); + console.log('revokedFlag is: ' + revokedFlag); } catch (error) { - console.log("isRevoked failed, errCode: " + error.code + ", errMsg: " + error.message); + let e: BusinessError = error as BusinessError; + console.error('isRevoked failed, errCode: ' + e.code + ', errMsg: ' + e.message); } + } else { + console.error('create x509 cert failed errCode: ' + err.code + ', errMsg: ' + err.message); + } + }) - // 业务需通过将public key二进制数据输入 @ohos.security.cryptoFramework的convertKey接口获取PubKey对象,此处省略 - let pubKey = null; - - // 证书吊销列表验签 - x509Crl.verify(pubKey, function (err, data) { + // The binary data of the public key needs to be passed to convertKey() of @ohos.security.cryptoFramework to obtain the PubKey object. The process is omitted here. + try { + let keyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_3'); + console.log('createAsyKeyGenerator success'); + let priEncodingBlob: cryptoFramework.DataBlob = { + data: priKeyData, + }; + let pubEncodingBlob: cryptoFramework.DataBlob = { + data: pubKeyData, + }; + keyGenerator.convertKey(pubEncodingBlob, priEncodingBlob, (e, keyPair) => { + if (e == null) { + console.log('convert key success'); + x509Crl.verify(keyPair.pubKey, (err, data) => { if (err == null) { - // 验签成功 - console.log("verify success"); + // The signature verification is successful. + console.log('verify success'); } else { - // 验签失败 - console.log("verify failed, errCode: " + err.code + ", errMsg: " + err.message); + // The signature verification failed. + console.error('verify failed, errCode: ' + err.code + ', errMsg: ' + err.message); } - }); + }); + } else { + console.error('convert key failed, message: ' + e.message + 'code: ' + e.code); + } + }) + } catch (error) { + let e: BusinessError = error as BusinessError; + console.error('get pubKey failed, errCode: ' + e.code + ', errMsg: ' + e.message); + } - // 证书序列号,业务需自行设置 - let serialNumber = 1000; + // Certificate serial number, which must be set based on the service. + let serialNumber = 1000; - // 获取被吊销证书对象 - try { - let entry = x509Crl.getRevokedCert(serialNumber); - } catch (error) { - console.log("getRevokedCert failed, errCode: " + error.code + ", errMsg: " + error.message); - } - }); + // Obtain the revoked certificate based on the serial number. + try { + let entry = x509Crl.getRevokedCert(serialNumber); + console.log('get getRevokedCert success'); + } catch (error) { + let e: BusinessError = error as BusinessError; + console.error('getRevokedCert failed, errCode: ' + e.code + ', errMsg: ' + e.message); + } + }); } ``` @@ -421,88 +507,88 @@ function crlSample() { 示例:创建证书链校验器对象,并对证书链数据进行校验(场景1) -```javascript -import cryptoCert from '@ohos.security.cert'; - -// 一级证书数据,此处仅示例,业务需自行设置真实数据 -let caCertData = "-----BEGIN CERTIFICATE-----\n" -+ "...\n" -+ "...\n" -+ "...\n" -+ "-----END CERTIFICATE-----\n"; - -// 二级证书数据,此处仅示例,业务需自行设置真实数据 -let secondCaCertData = "-----BEGIN CERTIFICATE-----\n" -+ "...\n" -+ "...\n" -+ "...\n" -+ "-----END CERTIFICATE-----\n"; - -// string转Uint8Array -function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; i++) { - arr.push(str.charCodeAt(i)); - } - return new Uint8Array(arr); +```ts +import certFramework from '@ohos.security.cert'; + +// CA certificate data, which is only an example. The CA certificate data varies with the service. +let caCertData = '-----BEGIN CERTIFICATE-----\n' + + '...\n' + + '...\n' + + '...\n' + + '-----END CERTIFICATE-----\n'; + +// End-entity certificate data, which is only an example. The certificate data varies with the service. +let secondCaCertData = '-----BEGIN CERTIFICATE-----\n' + + '...\n' + + '...\n' + + '...\n' + + '-----END CERTIFICATE-----\n'; + +// Convert the certificate data form a string to a Uint8Array.. +function stringToUint8Array(str: string): Uint8Array { + let arr: Array = []; + for (let i = 0, j = str.length; i < j; i++) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); } -// 证书链校验器示例:此示例中以校验二级证书链为例,业务需根据场景自行修改 -function certChainValidatorSample() { - // 证书链校验器算法,当前仅支持PKIX - let algorithm = "PKIX"; - - // 创建证书链校验器对象 - let validator = cryptoCert.createCertChainValidator(algorithm); - - // 一级证书数据 - let uint8ArrayOfCaCertData = stringToUint8Array(caCertData); - - // 一级证书数据长度 - let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer); - - // 二级证书数据 - let uint8ArrayOf2ndCaCertData = stringToUint8Array(secondCaCertData); - - // 二级证书数据长度 - let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer); - - // 证书链二进制数据:二级证书数据长度+二级证书数据+一级证书数据长度+一级证书数据(L-V格式) - let encodingData = new Uint8Array(uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + - uint8ArrayOfCaCertDataLen.length + uint8ArrayOfCaCertData.length); - for (var i = 0; i < uint8ArrayOf2ndCaCertDataLen.length; i++) { - encodingData[i] = uint8ArrayOf2ndCaCertDataLen[i]; - } - for (var i = 0; i < uint8ArrayOf2ndCaCertData.length; i++) { - encodingData[uint8ArrayOf2ndCaCertDataLen.length + i] = uint8ArrayOf2ndCaCertData[i]; - } - for (var i = 0; i < uint8ArrayOfCaCertDataLen.length; i++) { - encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + i] = uint8ArrayOfCaCertDataLen[i]; - } - for (var i = 0; i < uint8ArrayOfCaCertData.length; i++) { - encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + - uint8ArrayOfCaCertDataLen.length + i] = uint8ArrayOfCaCertData[i]; +// Certificate chain validator example. In this example, a two-level certificate chain is verified. +function certChainValidatorSample(): void { + // Certificate chain validator algorithm. Currently, only PKIX is supported. + let algorithm = 'PKIX'; + + // Create a CertChainValidator instance. + let validator = certFramework.createCertChainValidator(algorithm); + + // CA certificate data. + let uint8ArrayOfCaCertData = stringToUint8Array(caCertData); + + // Length of the CA certificate data. + let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer); + + // End-entity certificate data. + let uint8ArrayOf2ndCaCertData = stringToUint8Array(secondCaCertData); + + // Length of the end-entity certificate data. + let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer); + + // Certificate chain binary data: end-entity certificate data length + end-entity certificate data + CA certificate data length + CA certificate data (in L-V format). + let encodingData = new Uint8Array(uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + + uint8ArrayOfCaCertDataLen.length + uint8ArrayOfCaCertData.length); + for (let i = 0; i < uint8ArrayOf2ndCaCertDataLen.length; i++) { + encodingData[i] = uint8ArrayOf2ndCaCertDataLen[i]; + } + for (let i = 0; i < uint8ArrayOf2ndCaCertData.length; i++) { + encodingData[uint8ArrayOf2ndCaCertDataLen.length + i] = uint8ArrayOf2ndCaCertData[i]; + } + for (let i = 0; i < uint8ArrayOfCaCertDataLen.length; i++) { + encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + i] = uint8ArrayOfCaCertDataLen[i]; + } + for (let i = 0; i < uint8ArrayOfCaCertData.length; i++) { + encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + + uint8ArrayOfCaCertDataLen.length + i] = uint8ArrayOfCaCertData[i]; + } + + let certChainData: certFramework.CertChainData = { + // Uint8Array type: L-V format (certificate data length-certificate data) + data: encodingData, + // Number of certificates. It is 2 in this example. + count: 2, + // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format. + encodingFormat: certFramework.EncodingFormat.FORMAT_PEM + }; + + // Verify the certificate chain. + validator.validate(certChainData, (err, data) => { + if (err != null) { + // The operation fails. + console.error('validate failed, errCode: ' + err.code + ', errMsg: ' + err.message); + } else { + // The operation is successful. + console.log('validate success'); } - - let certChainData = { - // Uint8Array类型:L-V格式(证书数据长度-证书数据) - data: encodingData, - // 证书数量,此示例中为2 - count: 2, - // 证书格式:支持PEM和DER,此例中对应PEM - encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM - }; - - // 校验证书链 - validator.validate(certChainData, function (err, data) { - if (err != null) { - // 证书链校验失败 - console.log("validate failed, errCode: " + err.code + ", errMsg: " + err.message); - } else { - // 证书链校验成功 - console.log("validate success"); - } - }); + }); } ``` @@ -534,43 +620,75 @@ function certChainValidatorSample() { 示例:获取被吊销证书对象,并调用对象方法(包含场景1-3) -```javascript -import cryptoCert from '@ohos.security.cert'; +```ts +import certFramework from '@ohos.security.cert'; +import { BusinessError } from '@ohos.base'; + +let crlData = '-----BEGIN X509 CRL-----\n' + + 'MIHzMF4CAQMwDQYJKoZIhvcNAQEEBQAwFTETMBEGA1UEAxMKQ1JMIGlzc3VlchcN\n' + + 'MTcwODA3MTExOTU1WhcNMzIxMjE0MDA1MzIwWjAVMBMCAgPoFw0zMjEyMTQwMDUz\n' + + 'MjBaMA0GCSqGSIb3DQEBBAUAA4GBACEPHhlaCTWA42ykeaOyR0SGQIHIOUR3gcDH\n' + + 'J1LaNwiL+gDxI9rMQmlhsUGJmPIPdRs9uYyI+f854lsWYisD2PUEpn3DbEvzwYeQ\n' + + '5SqQoPDoM+YfZZa23hoTLsu52toXobP74sf/9K501p/+8hm4ROMLBoRT86GQKY6g\n' + + 'eavsH0Q3\n' + + '-----END X509 CRL-----\n' + +// Convert the certificate data form a string to a Uint8Array. +function stringToUint8Array(str: string): Uint8Array { + let arr: Array = []; + for (let i = 0, j = str.length; i < j; i++) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); +} -// 被吊销证书示例 -function crlEntrySample() { - // 业务需自行通过cryptoFramework的createX509Crl接口创建X509Crl对象,此处省略 - let x509Crl = null; - - // 获取被吊销证书对象,业务需根据场景调用X509Crl的接口获取,此示例使用getRevokedCert获取 - let serialNumber = 1000; - let crlEntry = null; - try { - crlEntry = x509Crl.getRevokedCert(serialNumber); - } catch (error) { - console.log("getRevokedCert failed, errCode: " + error.code + ", errMsg: " + error.message); +// Example of a revoked certificate. +function crlEntrySample(): void { + // Create an **X509Crl** instance by using createX509Crl() of certFramework. + let encodingBlob: certFramework.EncodingBlob = { + // Convert the CRL data from a string to a Uint8Array. + data: stringToUint8Array(crlData), + // CRL format. Only PEM and DER are supported. In this example, the CRL is in PEM format. + encodingFormat: certFramework.EncodingFormat.FORMAT_PEM + }; + + // Create an X509Crl instance. + certFramework.createX509Crl(encodingBlob, (err, x509Crl) => { + if (err != null) { + // Failed to create the X509Crl instance. + console.error('createX509Crl failed, errCode: ' + err.code + ', errMsg: ' + err.message); + return; } + console.log('create x509 crl success'); - // 获取被吊销证书的序列号 - serialNumber = crlEntry.getSerialNumber(); - - // 获取被吊销证书的吊销日期 + // Obtain a revoked certificate instance. In this example, the instance is obtained by using getRevokedCert(). try { - crlEntry.getRevocationDate(); - } catch (error) { - console.log("getRevocationDate failed, errCode: " + error.code + ", errMsg: " + error.message); - } + let serialNumber = 1000; + let crlEntry = x509Crl.getRevokedCert(serialNumber); + + // Obtain the serial number of the revoked certificate. + serialNumber = crlEntry.getSerialNumber(); + console.log('serialNumber is: ', serialNumber); + + // Obtain the revocation date of the revoked certificate. + let date = crlEntry.getRevocationDate(); + console.log('revocation date is: ', date); - // 获取被吊销证书对象的序列化数据 - crlEntry.getEncoded(function (err, data) { + // Obtain the serialized data of the revoked certificate instance. + crlEntry.getEncoded((err, data) => { if (err != null) { - // 获取序列化数据失败 - console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message); + // Failed to obtain the serialized data of the certificate. + console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message); } else { - // 获取序列化数据成功 - console.log("getEncoded success"); + // The serialized data of the certificate is successfully obtained. + console.log('getEncoded success'); } - }); + }); + } catch (error) { + let e: BusinessError = error as BusinessError; + console.error('getRevokedCert failed, errCode: ' + e.code + ', errMsg: ' + e.message); + } + }) } ```