1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16// [Start create_parse_verify_certificate_revocation_list_objects] 17 18 19import { cert } from '@kit.DeviceCertificateKit'; 20import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 21import { BusinessError } from '@kit.BasicServicesKit'; 22import { util } from '@kit.ArkTS'; 23 24// CRL数据,以下只是一个示例,需要根据具体业务来赋值 25let crlData = '-----BEGIN X509 CRL-----\n' + 26 'MIIByzCBtAIBATANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJDTjEPMA0GA1UE\n' + 27 'CAwG6ZmV6KW/MQ8wDQYDVQQHDAbopb/lrokxDzANBgNVBAoMBua1i+ivlTEVMBMG\n' + 28 'A1UEAwwM5Lit5paH5rWL6K+VFw0yNTAyMjAwNjEzMTZaFw0yNTAzMjIwNjEzMTZa\n' + 29 'MBkwFwIGAXKnJjrAFw0yNTAyMjAwNjEzMDNaoA4wDDAKBgNVHRQEAwIBADANBgkq\n' + 30 'hkiG9w0BAQsFAAOCAQEAt9AZ/B5FQiXnKKBGocKmM5QKeky/3etcI+cAVyD0zfjI\n' + 31 'r1UrL1aF+49LdZps3zQRqm4RQmo9CwL+KsMZiIMSeWF5Q6LW7BQa08hx5PtdjoOu\n' + 32 '1IWVKAwR5IigpaOwMKRTq1xJ372EiUkDD83AsxEkQoQW0bBvFklGrzglSACeKST+\n' + 33 'Pn6ywwFyYj34cfRuz3ueqwHRmN/mGzQdet7Ns8JBGWutDzfJsAiPC/TIaafTOocO\n' + 34 'CHo81Q2rMcqAJj5uXyc1Gq8KfOEqsxo/oDwReghjwrUedJ+9l/cQBr0F8HPV4H8W\n' + 35 '49sYMpseywjp9lxjWt/2nrx1z2yMaivGrVhoFasZvQ==\n' + 36 '-----END X509 CRL-----\n' 37 38let certData = '-----BEGIN CERTIFICATE-----\n' + 39 'MIIDgTCCAmmgAwIBAgIGAXKnJjrAMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYT\n' + 40 'AkNOMQ8wDQYDVQQIDAbpmZXopb8xDzANBgNVBAcMBuilv+WuiTEPMA0GA1UECgwG\n' + 41 '5rWL6K+VMRUwEwYDVQQDDAzkuK3mlofmtYvor5UwHhcNMjUwMjIwMDYwOTUyWhcN\n' + 42 'MzUwMjE4MDYwOTUyWjBXMQswCQYDVQQGEwJDTjEPMA0GA1UECAwG6ZmV6KW/MQ8w\n' + 43 'DQYDVQQHDAbopb/lrokxDzANBgNVBAoMBua1i+ivlTEVMBMGA1UEAwwM5Lit5paH\n' + 44 '5rWL6K+VMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2DQpPYN7cJjQ\n' + 45 'LWLlkP5dD8J/g1xx97t2bFciUOru14IBm9EeX6qkohDSl6kQHwfVSqTfcqdIn9We\n' + 46 '73FiitfDjHc9xxbvBKbCYicCzS/eNl0W9q14FiEB8M9vz4dpKK00KZBcGc1QK2m+\n' + 47 '/N6zw4Tw4wXZ97v6/M+bhY5X0b3qEJlgQNyz7dD0wF7SCuzLL9zbr403KktHMG5Y\n' + 48 'MzyOBaGOaMuVQFlXMV/E5OWfqbM7n0Pu/cGj+AfkkziWxB+5WFCRP6Pw64LJGo+e\n' + 49 'uZHgHp07kk6+a2YNnFMcdTsOIWBSpCvC3I612NjpBirn2bFRWqTD++YAuvJQagmM\n' + 50 '+VhIjXD48wIDAQABo1MwUTAdBgNVHQ4EFgQUIN7ulBn89L5HXh9m9JM7rpkvlXUw\n' + 51 'HwYDVR0jBBgwFoAUIN7ulBn89L5HXh9m9JM7rpkvlXUwDwYDVR0TAQH/BAUwAwEB\n' + 52 '/zANBgkqhkiG9w0BAQsFAAOCAQEAxWNa3LSOR3QOJ+wE1Y/q5zzEPWmWR5OMrRJK\n' + 53 'juBHhYbzsg3r74fBO3Hw8XggEpHr6SOI1rBpZhciA8D9E8RnM1aJLY53rpBDY5OV\n' + 54 'wxTFzrjdwIknt13t6ILfGeLye5OAF0S8VPdfDqP9NddNNr/WFKpd3tKoBlG0ObMa\n' + 55 'LaQvOqObz0MJrjKsyI680nJjFLjLZ6+lEDSg4rsGU+bxEkONerStAPNcN2x9z7O6\n' + 56 'YJOvhiLjWvr8VRjlMZYVmT9gqCImoo+7JaHbu8jz9mjRxD6fo9I1OvCLNFyFw2sV\n' + 57 'iYID9UEbT6IWv/kKBdr7Te9+SY6AWxUxO8Hd7HdPKDOCrGrU9A==\n' + 58 '-----END CERTIFICATE-----\n'; 59 60let pubKeyData = new Uint8Array([ 61 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 62 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 63 0x00, 0xd8, 0x34, 0x29, 0x3d, 0x83, 0x7b, 0x70, 0x98, 0xd0, 0x2d, 0x62, 0xe5, 0x90, 0xfe, 0x5d, 64 0x0f, 0xc2, 0x7f, 0x83, 0x5c, 0x71, 0xf7, 0xbb, 0x76, 0x6c, 0x57, 0x22, 0x50, 0xea, 0xee, 0xd7, 65 0x82, 0x01, 0x9b, 0xd1, 0x1e, 0x5f, 0xaa, 0xa4, 0xa2, 0x10, 0xd2, 0x97, 0xa9, 0x10, 0x1f, 0x07, 66 0xd5, 0x4a, 0xa4, 0xdf, 0x72, 0xa7, 0x48, 0x9f, 0xd5, 0x9e, 0xef, 0x71, 0x62, 0x8a, 0xd7, 0xc3, 67 0x8c, 0x77, 0x3d, 0xc7, 0x16, 0xef, 0x04, 0xa6, 0xc2, 0x62, 0x27, 0x02, 0xcd, 0x2f, 0xde, 0x36, 68 0x5d, 0x16, 0xf6, 0xad, 0x78, 0x16, 0x21, 0x01, 0xf0, 0xcf, 0x6f, 0xcf, 0x87, 0x69, 0x28, 0xad, 69 0x34, 0x29, 0x90, 0x5c, 0x19, 0xcd, 0x50, 0x2b, 0x69, 0xbe, 0xfc, 0xde, 0xb3, 0xc3, 0x84, 0xf0, 70 0xe3, 0x05, 0xd9, 0xf7, 0xbb, 0xfa, 0xfc, 0xcf, 0x9b, 0x85, 0x8e, 0x57, 0xd1, 0xbd, 0xea, 0x10, 71 0x99, 0x60, 0x40, 0xdc, 0xb3, 0xed, 0xd0, 0xf4, 0xc0, 0x5e, 0xd2, 0x0a, 0xec, 0xcb, 0x2f, 0xdc, 72 0xdb, 0xaf, 0x8d, 0x37, 0x2a, 0x4b, 0x47, 0x30, 0x6e, 0x58, 0x33, 0x3c, 0x8e, 0x05, 0xa1, 0x8e, 73 0x68, 0xcb, 0x95, 0x40, 0x59, 0x57, 0x31, 0x5f, 0xc4, 0xe4, 0xe5, 0x9f, 0xa9, 0xb3, 0x3b, 0x9f, 74 0x43, 0xee, 0xfd, 0xc1, 0xa3, 0xf8, 0x07, 0xe4, 0x93, 0x38, 0x96, 0xc4, 0x1f, 0xb9, 0x58, 0x50, 75 0x91, 0x3f, 0xa3, 0xf0, 0xeb, 0x82, 0xc9, 0x1a, 0x8f, 0x9e, 0xb9, 0x91, 0xe0, 0x1e, 0x9d, 0x3b, 76 0x92, 0x4e, 0xbe, 0x6b, 0x66, 0x0d, 0x9c, 0x53, 0x1c, 0x75, 0x3b, 0x0e, 0x21, 0x60, 0x52, 0xa4, 77 0x2b, 0xc2, 0xdc, 0x8e, 0xb5, 0xd8, 0xd8, 0xe9, 0x06, 0x2a, 0xe7, 0xd9, 0xb1, 0x51, 0x5a, 0xa4, 78 0xc3, 0xfb, 0xe6, 0x00, 0xba, 0xf2, 0x50, 0x6a, 0x09, 0x8c, 0xf9, 0x58, 0x48, 0x8d, 0x70, 0xf8, 79 0xf3, 0x02, 0x03, 0x01, 0x00, 0x01 80]); 81 82// CRL示例 83function crlSample(): void { 84 let textEncoder = new util.TextEncoder(); 85 let encodingBlob: cert.EncodingBlob = { 86 // 将CRL数据从string转为Unit8Array 87 data: textEncoder.encodeInto(crlData), 88 // CRL格式,仅支持PEM和DER格式。在这个例子中,CRL用的是PEM格式 89 encodingFormat: cert.EncodingFormat.FORMAT_PEM 90 }; 91 92 // 创建X509CRL实例 93 cert.createX509CRL(encodingBlob, (err, x509Crl) => { 94 if (err != null) { 95 // 创建X509CRL实例失败 96 console.error(`createX509Crl failed, errCode: ${err.code}, errMsg:${err.message} `); 97 return; 98 } 99 // 创建X509CRL实例成功 100 console.log('createX509CRL success'); 101 102 // 获取CRL的版本 103 let version = x509Crl.getVersion(); 104 let revokedType = x509Crl.getType(); 105 console.log(`X509 CRL version: ${version}, type :${revokedType}`); 106 107 // 公钥的二进制数据需要传入@ohos.security.cryptoFramework的convertKey()方法去获取公钥对象 108 try { 109 let keyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_3'); 110 console.log('createAsyKeyGenerator success'); 111 let pubEncodingBlob: cryptoFramework.DataBlob = { 112 data: pubKeyData, 113 }; 114 keyGenerator.convertKey(pubEncodingBlob, null, (e, keyPair) => { 115 if (e == null) { 116 console.log('convert key success'); 117 x509Crl.verify(keyPair.pubKey, (err, data) => { 118 if (err == null) { 119 // 签名验证成功 120 console.log('verify success'); 121 } else { 122 // 签名验证失败 123 console.error(`verify failed, errCode: ${err.code}, errMsg: ${err.message}`); 124 } 125 }); 126 } else { 127 console.error(`convert key failed, message: ${e.message}, code: ${e.code} `); 128 } 129 }) 130 } catch (error) { 131 let e: BusinessError = error as BusinessError; 132 console.error(`get pubKey failed, errCode: ${e.code}, errMsg: ${e.message}`); 133 } 134 135 // 使用certFramework的createX509Cert()方法创建一个X509Cert实例 136 let certBlob: cert.EncodingBlob = { 137 data: textEncoder.encodeInto(certData), 138 encodingFormat: cert.EncodingFormat.FORMAT_PEM 139 }; 140 let revokedFlag = true; 141 let serial: bigint = BigInt('0'); 142 cert.createX509Cert(certBlob, (err, cert) => { 143 serial = cert.getCertSerialNumber(); 144 if (err == null) { 145 try { 146 // 检查证书是否被吊销 147 revokedFlag = x509Crl.isRevoked(cert); 148 console.log(`revokedFlag is: ${revokedFlag}`); 149 if (!revokedFlag) { 150 console.log('the given cert is not revoked.'); 151 return; 152 } 153 // 根据序列号来获取被吊销的证书 154 try { 155 let crlEntry = x509Crl.getRevokedCert(serial); 156 console.log('get getRevokedCert success'); 157 let serialNumber = crlEntry.getSerialNumber(); 158 console.log(`crlEntry serialNumber is: ${serialNumber}`); 159 160 // 获取被吊销证书的吊销日期 161 let date = crlEntry.getRevocationDate(); 162 console.log(`revocation date is: ${date}`); 163 } catch (error) { 164 let e: BusinessError = error as BusinessError; 165 console.error(`getRevokedCert failed, errCode: ${e.code}, errMsg: ${e.message}`); 166 } 167 } catch (error) { 168 let e: BusinessError = error as BusinessError; 169 console.error(`isRevoked failed, errCode: ${e.code}, errMsg:${e.message}`); 170 } 171 } else { 172 console.error(`create x509 cert failed, errCode: ${err.code}, errMsg: ${err.message}`); 173 } 174 }) 175 }); 176} 177 178 179// [End create_parse_verify_certificate_revocation_list_objects] 180 181@Entry 182@Component 183struct Index { 184 @State message: string = 'CreateParseVerifyCrlObject'; 185 186 build() { 187 Column({ space: 5 }) { 188 Text(this.message) 189 .fontSize(25) 190 .fontWeight(FontWeight.Bold) 191 Button('Call CreateParseVerifyCrlObject') 192 .width('70%') 193 .onClick(() => { 194 try { 195 crlSample(); 196 this.message = 'Call Success'; 197 } catch { 198 this.message = 'Call Fail'; 199 } 200 }) 201 } 202 .height('100%') 203 .width('100%') 204 } 205}