From 9125a89dc2e5197e411c0f3a90aefed0da244531 Mon Sep 17 00:00:00 2001 From: xwb Date: Fri, 9 Jun 2023 14:59:27 +0800 Subject: [PATCH] add DSA,RSA,ECC,Rand algorithm Signed-off-by: xwb --- .../reference/apis/js-apis-cryptoFramework.md | 4236 ++++++++++------- .../security/cryptoFramework-guidelines.md | 873 +++- .../security/cryptoFramework-overview.md | 454 +- 3 files changed, 3599 insertions(+), 1964 deletions(-) diff --git a/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md b/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md index 0c80adbe72..75944328e1 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md +++ b/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md @@ -24,7 +24,7 @@ import cryptoFramework from "@ohos.security.cryptoFramework" | NOT_SUPPORT | 801 | 操作不支持。 | | ERR_OUT_OF_MEMORY | 17620001 | 内存错误。 | | ERR_RUNTIME_ERROR | 17620002 | 运行时外部错误。 | -| ERR_CRYPTO_OPERATION | 17630001 | 调用三方算法库API出错。 | +| ERR_CRYPTO_OPERATION | 17630001 | 调用三方算 法库API出错。 | ## DataBlob @@ -36,1991 +36,2616 @@ buffer数组。 | ---- | ---------- | ---- | ---- | ------ | | data | Uint8Array | 是 | 是 | 数据。 | +## ParamsSpec -## cryptoFramework.createMac +加解密参数,在进行对称加解密时需要构造其子类对象,并将子类对象传入[init()](#init-2)方法。
适用于需要iv等参数的对称加解密模式(对于无iv等参数的模式如ECB模式,无需构造,在[init()](#init-2)中传入null即可)。 -createMac(algName : string) : Mac +**系统能力:** SystemCapability.Security.CryptoFramework -生成Mac实例,用于进行消息认证码的计算与操作。
支持的规格详见框架概述“[HMAC消息认证码算法规格](../../security/cryptoFramework-overview.md#hmac消息认证码算法规格)”一节。 +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| algName | string | 是 | 是 | 指明对称加解密参数的算法模式。可选值如下:
- "IvParamsSpec": 适用于CBC\|CTR\|OFB\|CFB模式
- "GcmParamsSpec": 适用于GCM模式
- "CcmParamsSpec": 适用于CCM模式 | -**系统能力:** SystemCapability.Security.CryptoFramework +> **说明:** +> 由于[init()](#init-2)的params参数是ParamsSpec类型(父类),而实际需要传入具体的子类对象(如IvParamsSpec),因此在构造子类对象时应设置其父类ParamsSpec的algName参数,使算法库在init()时知道传入的是哪种子类对象。 -**参数:** +## IvParamsSpec -| 参数名 | 类型 | 必填 | 说明 | -| ------- | ------ | ---- | ------------------------------------------------------------ | -| algName | string | 是 | 指定摘要算法,支持算法请参考“[HMAC算法支持范围](../../security/cryptoFramework-overview.md#hmac消息认证码算法规格)”一节 | +加解密参数[ParamsSpec](#paramsspec)的子类,用于在对称加解密时作为[init()](#init-2)方法的参数。
适用于CBC、CTR、OFB、CFB这些仅使用iv作为参数的加解密模式。 -**返回值**: +**系统能力:** SystemCapability.Security.CryptoFramework -| 类型 | 说明 | -| ---- | --------------------------------------- | -| Mac | 返回由输入算法指定生成的[Mac](#mac)对象 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ---- | --------------------- | ---- | ---- | ------------------------------------------------------------ | +| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv。常见取值如下:
- AES的CBC\|CTR\|OFB\|CFB模式:iv长度为16字节
- 3DES的CBC\|OFB\|CFB模式:iv长度为8字节 | -**错误码:** +> **说明:** +> 传入[init()](#init-2)方法前需要指定其algName属性(来源于父类[ParamsSpec](#paramsspec))。 -| 错误码ID | 错误信息 | -| -------- | ------------------ | -| 17620001 | memory error. | +## GcmParamsSpec -**示例:** +加解密参数[ParamsSpec](#paramsspec)的子类,用于在对称加解密时作为[init()](#init-2)方法的参数。
适用于GCM模式。 -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +**系统能力:** SystemCapability.Security.CryptoFramework -var mac; -try { - // 参数选择请参考上述算法支持范围 - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); -} -``` +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | --------------------- | ---- | ---- | ------------------------------------------------------------ | +| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv,长度为12字节。 | +| aad | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数aad,长度为8字节。 | +| authTag | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数authTag,长度为16字节。
采用GCM模式加密时,需要获取[doFinal()](#dofinal-2)输出的[DataBlob](#datablob),取出其末尾16字节作为解密时[init()](#init-2)方法的入参[GcmParamsSpec](#gcmparamsspec)中的的authTag。 | -## Mac +> **说明:** +> 传入[init()](#init-2)方法前需要指定其algName属性(来源于父类[ParamsSpec](#paramsspec))。 -Mac类,调用Mac方法可以进行MAC(Message Authentication Code)加密计算。调用前,需要通过[createMac](#cryptoframeworkcreatemac)构造Mac实例。 +## CcmParamsSpec -### 属性 +加解密参数[ParamsSpec](#paramsspec)的子类,用于在对称加解密时作为[init()](#init-2)方法的参数。
适用于CCM模式。 **系统能力:** SystemCapability.Security.CryptoFramework -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | -------------------- | -| algName | string | 是 | 否 | 代表指定的摘要算法名 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | --------------------- | ---- | ---- | ------------------------------------------------------------ | +| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv,长度为7字节。 | +| aad | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数aad,长度为8字节。 | +| authTag | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数authTag,长度为12字节。
采用CCM模式加密时,需要获取[doFinal()](#dofinal-2)输出的[DataBlob](#datablob),取出其末尾12字节作为解密时[init()](#init-2)方法的入参[CcmParamsSpec](#ccmparamsspec)中的authTag。 | -### init +> **说明:** +> 传入[init()](#init-2)方法前需要指定其algName属性(来源于父类[ParamsSpec](#paramsspec))。 -init(key : SymKey, callback : AsyncCallback\) : void; +## CryptoMode -使用对称密钥初始化Mac计算 +表示加解密操作的枚举。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** +| 名称 | 值 | 说明 | +| ------------ | ---- | ------------------ | +| ENCRYPT_MODE | 0 | 表示进行加密操作。 | +| DECRYPT_MODE | 1 | 表示进行解密操作。 | -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ------------ | -| key | [SymKey](#symkey) | 是 | 共享对称密钥 | -| callback | AsyncCallback\ | 是 | 回调函数 | +## AsyKeySpecItem10+ -**错误码:** +表示密钥参数的枚举。 -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17630001 | crypto operation error. | +**系统能力:** SystemCapability.Security.CryptoFramework -**示例:** +| 名称 | 值 | 说明 | +| ------------ | ---- | ---------------- | +| DSA_P_BN | 101 | DSA算法的素模数p。 | +| DSA_Q_BN | 102 | DSA算法中密钥参数q(p-1的素因子)。 | +| DSA_G_BN | 103 | DSA算法的参数g。 | +| DSA_SK_BN | 104 | DSA算法的私钥sk。 | +| DSA_PK_BN | 105 | DSA算法的公钥pk。 | +| ECC_FP_P_BN | 201 | DSA算法中表示椭圆曲线Fp域的素数p。 | +| ECC_A_BN | 202 | DSA算法中椭圆曲线的第一个系数a。 | +| ECC_B_BN | 203 | DSA算法中椭圆曲线的第二个系数b。 | +| ECC_G_X_BN | 204 | ECC算法中基点g的x坐标。 | +| ECC_G_Y_BN | 205 | ECC算法中基点g的y坐标。 | +| ECC_N_BN | 206 | ECC算法中基点g的阶n。 | +| ECC_H_NUM | 207 | ECC算法中的余因子h。 | +| ECC_SK_BN | 208 | ECC算法中的私钥sk。 | +| ECC_PK_X_BN | 209 | ECC算法中,公钥pk(椭圆曲线上的一个点)的x坐标。 | +| ECC_PK_Y_BN | 210 | ECC算法中,公钥pk(椭圆曲线上的一个点)的y坐标。 | +| ECC_FIELD_TYPE_STR | 211 | ECC算法中,椭圆曲线的域类型(当前只支持Fp域)。 | +| ECC_FIELD_SIZE_NUM | 212 | ECC算法中域的大小,单位为bits(注:对于Fp域,域的大小为素数p的bits长度)。 | +| ECC_CURVE_NAME_STR | 213 | ECC算法中的SECG曲线名称。 | +| RSA_N_BN | 301 | RSA算法中的模数n。 | +| RSA_SK_BN | 302 | RSA算法中的私钥sk(即私钥指数d)。 | +| RSA_PK_BN | 303 | RSA算法中的公钥pk(即公钥指数e)。 | + +## AsyKeySpecType10+ + +表示密钥参数类型的枚举。 -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +**系统能力:** SystemCapability.Security.CryptoFramework -var mac; -try { - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); -} -var KeyBlob; -var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); -symKeyGenerator.convertKey(KeyBlob, (err, symKey) => { - if (err) { - console.error("[Callback] err: " + err.code); - } - mac.init(symKey, (err1, ) => { - if (err1) { - console.error("[Callback] err: " + err1.code); - } - }); -}); -``` +| 名称 | 值 | 说明 | +| ------------ | ---- | ---------------- | +| COMMON_PARAMS_SPEC | 0 | 表示公私钥中包含的公共参数。使用此类型的参数可以调用generateKeyPair // todo 随机生成密钥对。 | +| PRIVATE_KEY_SPEC | 1 | 表示私钥中包含的参数。使用此类型的参数可以调用generatePriKey生成指定的私钥。 | +| PUBLIC_KEY_SPEC | 2 | 表示公钥中包含的参数。使用此类型的参数可以调用generatePubKey生成指定的公钥。 | +| KEY_PAIR_SPEC | 3 | 表示公私钥中包含的全量参数。使用此类型的参数可以调用generateKeyPair生成指定的密钥对。 | -### init +## CipherSpecItem10+ + +表示加解密参数的枚举,这些加解密参数支持通过[setCipherSpec](#setcipherspec)接口设置/通过[getCipherSpec](#getcipherspec)接口获取。
当前只支持RSA算法。 -init(key : SymKey) : Promise\; +**系统能力:** SystemCapability.Security.CryptoFramework + +| 名称 | 值 | 说明 | +| ------------ | ---- | ---------------- | +| OAEP_MD_NAME_STR | 100 | 表示RSA算法中,使用PKCS1_OAEP模式时,消息摘要功能的算法名。 | +| OAEP_MGF_NAME_STR | 101 | 表示RSA算法中,使用PKCS1_OAEP模式时,掩码生成算法(目前仅支持MGF1)。 | +| OAEP_MGF1_MD_STR | 102 | 表示RSA算法中,使用PKCS1_OAEP模式时,MGF1掩码生成功能的消息摘要算法。 | +| OAEP_MGF1_PSRC_UINT8ARR | 103 | 表示RSA算法中,使用PKCS1_OAEP模式时,pSource的字节流。 | -使用对称密钥初始化Mac计算 +## SignSpecItem10+ + +表示签名验签参数的枚举,这些签名验签参数支持通过[setSignSpec](#setsignspec)、[setVerifySpec](#setverifyspec)接口设置/通过[getSignSpec](#getsignspec)、[getVerifySpec](#getverifyspec)接口获取。
当前只支持RSA算法。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** +| 名称 | 值 | 说明 | +| ------------ | ---- | ---------------- | +| PSS_MD_NAME_STR | 100 | 表示RSA算法中,使用PSS模式时,消息摘要功能的算法名。 | +| PSS_MGF_NAME_STR | 101 | 表示RSA算法中,使用PSS模式时,掩码生成算法(目前仅支持MGF1)。 | +| PSS_MGF1_MD_STR | 102 | 表示RSA算法中,使用PSS模式时,MGF1掩码生成功能的消息摘要参数。 | +| PSS_SALT_LEN_NUM | 103 | 表示RSA算法中,使用PSS模式时,盐值的长度,长度以字节为单位。 | +| PSS_TRAILER_FIELD_NUM | 104 | 表示RSA算法中,使用PSS模式时,用于编码操作的整数,值为1。 | -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ------ | ---- | ------------ | -| key | [SymKey](#symkey) | 是 | 共享对称密钥 | +## AsyKeySpec10+ -**返回值:** +指定非对称密钥参数的基本接口,用于创建密钥生成器。在指定非对称密钥参数时需要构造其子类对象,并将子类对象传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。构造子类对象时,所有bigint类型的密钥参数均采用大端写法,并使用正数。 -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +**系统能力:** SystemCapability.Security.CryptoFramework -**错误码:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| algName | string | 是 | 是 | 指定非对称密钥的算法名称,比如"RSA"、"DSA"、"ECC"。 | +| specType | [AsyKeySpecType](#asykeyspectype) | 是 | 是 | 指定密钥参数类型,用于区分公/私钥参数。 | -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17630001 | crypto operation error. | +## DSACommonParamsSpec10+ -**示例:** +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定DSA算法中公私钥包含的公共参数,随机生成公/私钥。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +**系统能力:** SystemCapability.Security.CryptoFramework -var mac; -try { - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Mac algName is: " + mac.algName); +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| p | bigint | 是 | 是 | 指定DSA算法的素模数p。 | +| q | bigint | 是 | 是 | 指定DSA算法中密钥参数q(p-1的素因子)。 | +| g | bigint | 是 | 是 | 指定DSA算法的参数g。 | -var KeyBlob; -var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); -var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); -promiseConvertKey.then(symKey => { - var promiseMacInit = mac.init(symKey); - return promiseMacInit; -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); +## DSAPubKeySpec10+ -``` +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定DSA算法中公钥包含的参数。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -### update +**系统能力:** SystemCapability.Security.CryptoFramework -update(input : DataBlob, callback : AsyncCallback\) : void; +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| params | [DSACommonParamsSpec](#dsacommonparamsspec) | 是 | 是 | 指定DSA算法中公私钥都包含的公共参数。 | +| pk | bigint | 是 | 是 | 指定DSA算法的公钥。 | -传入消息进行Mac更新计算 +## DSAKeyPairSpec10+ -> **说明:** -> Hmac算法多次调用update更新的代码示例详见开发指导“[使用消息认证码操作](../../security/cryptoFramework-guidelines.md#使用消息认证码操作)”。 +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定DSA算法中公私钥包含的全量参数。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| params | [DSACommonParamsSpec](#dsacommonparamsspec) | 是 | 是 | 指定DSA算法中公私钥都包含的公共参数。 | +| sk | bigint | 是 | 是 | 指定DSA算法的私钥sk。 | +| pk | bigint | 是 | 是 | 指定DSA算法的公钥pk。 | -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------- | -| input | [DataBlob](#datablob)| 是 | 传入的消息 | -| callback | AsyncCallback\ | 是 | 回调函数 | +## ECField10+ -**错误码:** +指定椭圆曲线的域。当前只支持Fp域。 -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17630001 | crypto operation error. | +**系统能力:** SystemCapability.Security.CryptoFramework -**示例:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| fieldType | string | 是 | 是 | 指定椭圆曲线域的类型,当前只支持"Fp"。 | -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +## ECFieldFp10+ -var KeyBlob; -var mac; -try { - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} -var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); -symKeyGenerator.convertKey(KeyBlob, (err, symKey) => { - if (err) { - console.error("[Callback] err: " + err.code); - } - mac.init(symKey, (err1, ) => { - if (err1) { - console.error("[Callback] err: " + err1.code); - } - let blob; - mac.update(blob, (err2, data) => { - if (err2) { - console.error("[Callback] err: " + err2.code); - } - }); - }); -}); -``` +指定椭圆曲线素数域。是[ECField](#ecfield)的子类。 -### update +**系统能力:** SystemCapability.Security.CryptoFramework -update(input : DataBlob) : Promise\; +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| p | bigint | 是 | 是 | 指定素数p。 | -传入消息进行Mac更新计算 +## Point10+ -> **说明:** -> Hmac算法多次调用update更新的代码示例详见开发指导“[使用消息认证码操作](../../security/cryptoFramework-guidelines.md#使用消息认证码操作)”。 +指定椭圆曲线上的一个点。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| x | bigint | 是 | 是 | 指定椭圆曲线上,点的x坐标。 | +| y | bigint | 是 | 是 | 指定椭圆曲线上,点的y坐标。 | -| 参数名 | 类型 | 必填 | 说明 | -| ------ | -------- | ---- | ---------- | -| input | [DataBlob](#datablob) | 是 | 传入的消息 | +## ECCCommonParamsSpec10+ -**返回值:** +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定ECC算法中公私钥包含的公共参数,随机生成公/私钥。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +**系统能力:** SystemCapability.Security.CryptoFramework -**错误码:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| field | [ECField](#ecfield) | 是 | 是 | 指定椭圆曲线的域(当前只支持Fp域)。 | +| a | bigint | 是 | 是 | 指定椭圆曲线的第一个系数a。 | +| b | bigint | 是 | 是 | 指定椭圆曲线的第二个系数b。 | +| g | [Point](#point) | 是 | 是 | 指定基点g。 | +| n | bigint | 是 | 是 | 指定基点g的阶数n。 | +| h | number | 是 | 是 | 指定余因子h。 | -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17630001 | crypto operation error. | +## ECCPriKeySpec10+ -**示例:** +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定ECC算法中私钥包含的参数。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +**系统能力:** SystemCapability.Security.CryptoFramework -var mac; -try { - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Mac algName is: " + mac.algName); +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| params | [ECCCommonParamsSpec](#ecccommonparamsspec) | 是 | 是 | 指定ECC算法中公私钥都包含的公共参数。 | +| sk | bigint | 是 | 是 | 指定ECC算法的私钥sk。 | -var KeyBlob; -var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); -var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); -promiseConvertKey.then(symKey => { - var promiseMacInit = mac.init(symKey); - return promiseMacInit; -}).then(() => { - let blob; - var promiseMacUpdate = mac.update(blob); - return promiseMacUpdate; -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); +## ECCPubKeySpec10+ -``` +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定ECC算法中公钥包含的参数。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -### doFinal +**系统能力:** SystemCapability.Security.CryptoFramework + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| params | [ECCCommonParamsSpec](#ecccommonparamsspec) | 是 | 是 | 指定ECC算法中公私钥都包含的公共参数。 | +| pk | [Point](#point) | 是 | 是 | 指定ECC算法的公钥pk。 | -doFinal(callback : AsyncCallback\) : void; +## ECCKeyPairSpec10+ -返回Mac的计算结果 +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定ECC算法中公私钥包含的全量参数。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| params | [ECCCommonParamsSpec](#ecccommonparamsspec) | 是 | 是 | 指定ECC算法中公私钥都包含的公共参数。 | +| sk | bigint | 是 | 是 | 指定ECC算法的私钥sk。 | +| pk | [Point](#point) | 是 | 是 | 指定ECC算法的公钥pk。 | -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------ | ---- | -------- | -| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数 | +## RSACommonParamsSpec10+ -**错误码:** +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定RSA算法中公私钥包含的公共参数,随机生成公/私钥。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17630001 | crypto operation error. | +**系统能力:** SystemCapability.Security.CryptoFramework -**示例:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| n | bigint | 是 | 是 | 指定模数n。 | -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +## RSAPubKeySpec10+ -var KeyBlob; -var mac; -try { - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} -var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); -symKeyGenerator.convertKey(KeyBlob, (err, symKey) => { - if (err) { - console.error("[Callback] err: " + err.code); - } - mac.init(symKey, (err1, ) => { - if (err1) { - console.error("[Callback] err: " + err1.code); - } - let blob; - mac.update(blob, (err2, ) => { - if (err2) { - console.error("[Callback] err: " + err2.code); - } - mac.doFinal((err3, macOutput) => { - if (err3) { - console.error("[Callback] err: " + err3.code); - } else { - console.error("[Promise]: HMAC result: " + macOutput); - } - }); - }); - }); -}); -``` - -### doFinal +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定RSA算法中公钥包含的参数。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -doFinal() : Promise\ +**系统能力:** SystemCapability.Security.CryptoFramework -返回Mac的计算结果 +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| params | [RSACommonParamsSpec](#rsacommonparamsspec) | 是 | 是 | 指定RSA算法中公私钥都包含的公共参数。 | +| pk | bigint | 是 | 是 | 指定RSA算法的公钥pk。 | -**系统能力:** SystemCapability.Security.CryptoFramework +## RSAKeyPairSpec10+ -**返回值:** +密钥参数[AsyKeySpec](#asykeyspec)的子类,用于指定RSA算法中公私钥包含的全量参数。
在使用密钥参数生成密钥时,将其传入[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法创建密钥生成器。 -| 类型 | 说明 | -| ------------------ | ----------- | -| Promise\<[DataBlob](#datablob)> | Promise对象 | +**系统能力:** SystemCapability.Security.CryptoFramework -**错误码:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | +| params | [RSACommonParamsSpec](#rsacommonparamsspec) | 是 | 是 | 指定RSA算法中公私钥都包含的公共参数。 | +| sk | bigint | 是 | 是 | 指定RSA算法的私钥sk。 | +| pk | bigint | 是 | 是 | 指定RSA算法的公钥pk。 | -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17630001 | crypto operation error. | +## Key -**示例:** +密钥(父类),在运行密码算法(如加解密)时需要提前生成其子类对象,并传入[Cipher](#cipher)实例的[init()](#init-2)方法。
密钥可以通过密钥生成器来生成。 -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +### 属性 -var mac; -try { - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Mac algName is: " + mac.algName); +**系统能力:** SystemCapability.Security.CryptoFramework -var KeyBlob; -var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); -var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); -promiseConvertKey.then(symKey => { - var promiseMacInit = mac.init(symKey); - return promiseMacInit; -}).then(() => { - let blob; - var promiseMacUpdate = mac.update(blob); - return promiseMacUpdate; -}).then(() => { - var PromiseMacDoFinal = mac.doFinal(); - return PromiseMacDoFinal; -}).then(macOutput => { - console.error("[Promise]: HMAC result: " + macOutput.data); -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); -``` +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------------- | +| format | string | 是 | 否 | 密钥的格式。 | +| algName | string | 是 | 否 | 密钥对应的算法名(含长度)。 | -### getMacLength +### getEncoded -getMacLength() : number +getEncoded(): DataBlob -获取Mac消息认证码的长度(字节数) +以同步方法,获取密钥数据的字节流。密钥可以为对称密钥,公钥或者私钥。其中,公钥格式满足ASN.1语法、X.509规范、DER编码格式;私钥格式满足ASN.1语法,PKCS#8规范、DER编码方式。 **系统能力:** SystemCapability.Security.CryptoFramework **返回值:** -| 类型 | 说明 | -| ------ | ------------------------- | -| number | 返回mac计算结果的字节长度 | +| 类型 | 说明 | +| --------------------- | ------------------------ | +| [DataBlob](#datablob) | 用于查看密钥的具体内容。 | **错误码:** +> **说明:**
+> 从API version 10开始,该接口支持抛出错误码。 + | 错误码ID | 错误信息 | | -------- | ---------------------- | +| 801 | this operation is not supported. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | **示例:** -```javascript +```js import cryptoFramework from "@ohos.security.cryptoFramework" - -var mac; -try { - mac = cryptoFramework.createMac("SHA256"); -} catch (error) { - console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +function uint8ArrayToShowStr(uint8Array) { + return Array.prototype.map + .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2)) + .join(''); } -console.error("Mac algName is: " + mac.algName); -var KeyBlob; -var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); -var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); -promiseConvertKey.then(symKey => { - var promiseMacInit = mac.init(symKey); - return promiseMacInit; -}).then(() => { - let blob; - var promiseMacUpdate = mac.update(blob); - return promiseMacUpdate; -}).then(() => { - var PromiseMacDoFinal = mac.doFinal(); - return PromiseMacDoFinal; -}).then(macOutput => { - console.error("[Promise]: HMAC result: " + macOutput.data); - let macLen = mac.getMacLength(); - console.error("MAC len: " + macLen); -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); +let key; // key为使用密钥生成器 生成的密钥,此处省略生成过程 +let encodedKey = key.getEncoded(); +console.info("key hex:" + uint8ArrayToShowStr(encodedKey.data)); ``` -## cryptoFramework.createMd - -createMd(algName : string) : Md - -生成Md实例,用于进行消息摘要的计算与操作。
支持的规格详见框架概述“[MD消息摘要算法规格](../../security/cryptoFramework-overview.md#md消息摘要算法规格)”一节。 - -**系统能力:** SystemCapability.Security.CryptoFramework - -**参数:** +## SymKey -| 参数名 | 类型 | 必填 | 说明 | -| ------- | ------ | ---- | ------------------------------------------------------------ | -| algName | string | 是 | 指定摘要算法,支持算法请参考“[MD算法支持范围](../../security/cryptoFramework-overview.md#md消息摘要算法规格)”一节 | +对称密钥,是[Key](#key)的子类,在对称加解密时需要将其对象传入[Cipher](#cipher)实例的[init()](#init-2)方法使用。
对称密钥可以通过对称密钥生成器[SymKeyGenerator](#symkeygenerator)来生成。 -**返回值**: +### clearMem -| 类型 | 说明 | -| ---- | ------------------------------------- | -| Md | 返回由输入算法指定生成的[Md](#md)对象 | +clearMem(): void -**错误码:** +以同步方法,将系统底层内存中的的密钥内容清零。建议在不再使用对称密钥实例时,调用本函数,避免内存中密钥数据存留过久。 -| 错误码ID | 错误信息 | -| -------- | ------------------ | -| 17620001 | memory error. | +**系统能力:** SystemCapability.Security.CryptoFramework **示例:** -```javascript +```js import cryptoFramework from "@ohos.security.cryptoFramework" - -var md; -try { - // 参数选择请参考上述算法支持范围 - md = cryptoFramework.createMd("SHA256"); -} catch (error) { - console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +function uint8ArrayToShowStr(uint8Array) { + return Array.prototype.map + .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2)) + .join(''); } + +let key; // key为使用对称密钥生成器 生成的密钥,此处省略生成过程 +let encodedKey = key.getEncoded(); +console.info("key hex:" + uint8ArrayToShowStr(encodedKey.data)); // 输出密钥内容 +key.clearMem(); +encodedKey = key.getEncoded(); +console.info("key hex:" + uint8ArrayToShowStr(encodedKey.data)); // 输出全零 ``` -## Md +## PubKey -Md类,调用Md方法可以进行MD(Message Digest)摘要计算。调用前,需要通过[createMd](#cryptoframeworkcreatemd)构造Md实例。 +公钥,是Key的子类,在非对称加解密、验签、密钥协商时需要将其对象作为输入使用。
公钥可以通过非对称密钥生成器[AsyKeyGenerator](#asykeygenerator)、[AsyKeyGeneratorBySpec](#asykeygeneratorbyspec)来生成。 ### 属性 -**系统能力:** SystemCapability.Security.CryptoFramework - -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | -------------------- | -| algName | string | 是 | 否 | 代表指定的摘要算法名 | +**系统能力:** SystemCapability.Security.CryptoFramework -### update +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------------- | +| format | string | 是 | 否 | 密钥的格式。 | +| algName | string | 是 | 否 | 密钥对应的算法名(含长度)。 | -update(input : DataBlob, callback : AsyncCallback\) : void; +### getAsyKeySpec10+ -传入消息进行Md更新计算 +getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number -> **说明:** -> Md算法多次调用update更新的代码示例详见开发指导“[使用摘要操作](../../security/cryptoFramework-guidelines.md#使用摘要操作)”。 +以同步方法,获取密钥参数。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------- | -| input | [DataBlob](#datablob)| 是 | 传入的消息 | -| callback | AsyncCallback\ | 是 | 回调函数 | +| 参数名 | 类型 | 必填 | 说明 | +| ---- | --------------------- | ---- | -------------------- | +| item | [AsyKeySpecItem](#asykeyspecitem) | 是 | 指定的密钥参数。 | + +**返回值:** + +| 类型 | 说明 | +| --------------------------- | --------------------------------- | +| bigint\|string\|number | 用于查看密钥参数的具体内容。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +```js +let key; // key为公钥对象,此处省略生成过程 +let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN); +console.info("ecc item --- p: " + p.toString(16)); +``` -var md; -try { - md = cryptoFramework.createMd("SHA256"); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Md algName is: " + md.algName); +## PriKey -let blob; -md.update(blob, (err,) => { - if (err) { - console.error("[Callback] err: " + err.code); - } -}); -``` +私钥,是Key的子类,在非对称加解密、签名、密钥协商时需要将其作为输入使用。
私钥可以通过非对称密钥生成器[AsyKeyGenerator](#asykeygenerator)、[AsyKeyGeneratorBySpec](#asykeygeneratorbyspec)来生成。 -### update +### 属性 + +**系统能力:** SystemCapability.Security.CryptoFramework + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------------- | +| format | string | 是 | 否 | 密钥的格式。 | +| algName | string | 是 | 否 | 密钥对应的算法名(含长度)。 | -update(input : DataBlob) : Promise\; +### clearMem -传入消息进行Md更新计算 +clearMem(): void -> **说明:** -> Md算法多次调用update更新的代码示例详见开发指导“[使用摘要操作](../../security/cryptoFramework-guidelines.md#使用摘要操作)”。 +以同步方法,将系统底层内存中的的密钥内容清零。 **系统能力:** SystemCapability.Security.CryptoFramework -| 参数名 | 类型 | 必填 | 说明 | -| ------ | -------- | ---- | ---------- | -| input | DataBlob | 是 | 传入的消息 | +**示例:** + +```js +let key; // key为使用非对称密钥生成器生成的非对称密钥的私钥对象,此处省略生成过程 +key.clearMem(); +``` + +### getAsyKeySpec10+ + +getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number + +以同步方法,获取密钥参数。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---- | --------------------- | ---- | -------------------- | +| item | [AsyKeySpecItem](#asykeyspecitem) | 是 | 指定的密钥参数类型。 | **返回值:** -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +| 类型 | 说明 | +| --------------------------- | --------------------------------- | +| bigint\|string\|number | 用于查看密钥参数的具体内容。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +```js +let key; // key为私钥对象,此处省略生成过程 +let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN); +console.info("ecc item --- p: " + p.toString(16)); +``` -var md; -try { - md = cryptoFramework.createMd("SHA256"); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Md algName is: " + md.algName); - -let blob; -var promiseMdUpdate = md.update(blob); -promiseMdUpdate.then(() => { - // do something -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); -``` +## KeyPair -### digest +非对称密钥对,包含:公钥与私钥。
可以通过非对称密钥生成器[AsyKeyGenerator](#asykeygenerator)、[AsyKeyGeneratorBySpec](#asykeygeneratorbyspec)来生成。 -digest(callback : AsyncCallback\) : void +> **说明:** +> +> KeyPair对象中的pubKey对象和priKey对象,作为KeyPair对象中的一个参数存在,当离开KeyPair对象作用域时,其内部对象可能被析构。
业务方使用时应持有KeyPair对象的引用,而非内部pubKey或priKey对象的引用。 -返回Md的计算结果 +### 属性 **系统能力:** SystemCapability.Security.CryptoFramework -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------ | ---- | -------- | -| callback | AsyncCallback\ | 是 | 回调函数 | - -**错误码:** - -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17630001 | crypto operation error. | - -**示例:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------ | +| priKey | [PriKey](#prikey) | 是 | 否 | 私钥。 | +| pubKey | [PubKey](#pubkey) | 是 | 否 | 公钥。 | -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" -var md; -try { - md = cryptoFramework.createMd("SHA256"); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Md algName is: " + md.algName); +## cryptoFramework.createSymKeyGenerator -let blob; -md.update(blob, (err,) => { - if (err) { - console.error("[Callback] err: " + err.code); - } - md.digest((err1, mdOutput) => { - if (err1) { - console.error("[Callback] err: " + err1.code); - } else { - console.error("[Callback]: MD result: " + mdOutput); - } - }); -}); -``` +createSymKeyGenerator(algName: string): SymKeyGenerator -### digest +通过指定算法名称的字符串,获取相应的对称密钥生成器实例。
支持的规格详见框架概述“[密钥生成规格](../../security/cryptoFramework-overview.md#密钥生成规格)”一节。 -digest() : Promise\ +**系统能力:** SystemCapability.Security.CryptoFramework -返回Md的计算结果 +**参数:** -**系统能力:** SystemCapability.Security.CryptoFramework +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | ------------------------------------------------------------ | +| algName | string | 是 | 待生成对称密钥生成器的算法名称。
具体取值详见框架概述“[密钥生成规格](../../security/cryptoFramework-overview.md#密钥生成规格)”一节中的“字符串参数”。 | **返回值:** -| 类型 | 说明 | -| ------------------ | ----------- | -| Promise\<[DataBlob](#datablob)> | Promise对象 | - -**错误码:** +| 类型 | 说明 | +| ----------------------------------- | -------------------------- | +| [SymKeyGenerator](#symkeygenerator) | 返回对称密钥生成器的对象。 | | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17630001 | crypto operation error. | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; +let symKeyGenerator = cryptoFramework.createSymKeyGenerator('3DES192'); +``` -var md; -try { - md = cryptoFramework.createMd("SHA256"); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Md algName is: " + md.algName); +## SymKeyGenerator -let blob; -var promiseMdUpdate = md.update(blob); -promiseMdUpdate.then(() => { - var PromiseMdDigest = md.digest(); - return PromiseMdDigest; -}).then(mdOutput => { - console.error("[Promise]: MD result: " + mdOutput.data); -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); -``` +对称密钥生成器。
在使用该类的方法前,需要先使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)方法构建一个symKeyGenerator实例。 -### getMdLength +### 属性 + +**系统能力:** SystemCapability.Security.CryptoFramework + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ------------------------------ | +| algName | string | 是 | 否 | 对称密钥生成器指定的算法名称。 | + +### generateSymKey -getMdLength() : number +generateSymKey(callback: AsyncCallback\): void -获取Md消息摘要长度(字节数) +异步获取对称密钥生成器随机生成的密钥,通过注册回调函数获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。
目前支持使用OpenSSL的RAND_priv_bytes()作为底层能力生成随机密钥。 **系统能力:** SystemCapability.Security.CryptoFramework -**返回值:** +**参数:** -| 类型 | 说明 | -| ------ | ------------------------ | -| number | 返回md计算结果的字节长度 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------------- | ---- | ------------------------------------------------------------ | +| callback | AsyncCallback\<[SymKey](#symkey)> | 是 | 回调函数。当生成对称密钥成功,err为undefined,data为获取到的SymKey;否则为错误对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17630001 | crypto operation error. | +| 错误码ID | 错误信息 | +| -------- | ------------- | +| 17620001 | memory error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" - -var md; -try { - md = cryptoFramework.createMd("SHA256"); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} -console.error("Md algName is: " + md.algName); - -let blob; -var promiseMdUpdate = md.update(blob); -promiseMdUpdate.then(() => { - var PromiseMdDigest = md.digest(); - return PromiseMdDigest; -}).then(mdOutput => { - console.error("[Promise]: MD result: " + mdOutput.data); - let mdLen = md.getMdLength(); - console.error("MD len: " + mdLen); -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; +let symAlgName = '3DES192'; +let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); +symKeyGenerator.generateSymKey((err, symKey) => { + if (err) { + console.error(`Generate symKey failed, ${err.code}, ${err.message}`); + } else { + console.info(`Generate symKey success, algName: ${symKey.algName}`); + } +}) ``` -## cryptoFramework.createRandom +### generateSymKey -createRandom() : Random +generateSymKey(): Promise\ -生成Random实例,用于进行随机数的计算与设置种子。 +异步获取该对称密钥生成器随机生成的密钥,通过Promise获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。
目前支持使用OpenSSL的RAND_priv_bytes()作为底层能力生成随机密钥。 **系统能力:** SystemCapability.Security.CryptoFramework -**返回值**: +**返回值:** -| 类型 | 说明 | -| ------ | --------------------------------------------- | -| Random | 返回由输入算法指定生成的[Random](#random)对象 | +| 类型 | 说明 | +| --------------------------- | --------------------------------- | +| Promise\<[SymKey](#symkey)> | Promise对象,返回对称密钥SymKey。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ------------ | +| 错误码ID | 错误信息 | +| -------- | ------------- | | 17620001 | memory error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" - -try { - var rand = cryptoFramework.createRandom(); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; +let symAlgName = 'AES128'; +let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); +symKeyGenerator.generateSymKey() +.then(symKey => { + console.info(`Generate symKey success, algName: ${symKey.algName}`); +}, error => { + console.error(`Generate symKey failed, ${error.code}, ${error.message}`); +}) ``` -## Random - -Random类,调用Random方法可以进行随机数计算。调用前,需要通过[createRandom](#cryptoframeworkcreaterandom)构造Random实例。 - -### generateRandom +### convertKey -generateRandom(len : number, callback: AsyncCallback\) : void; +convertKey(key: DataBlob, callback: AsyncCallback\): void -生成指定长度的随机数 +异步根据指定数据生成对称密钥,通过注册回调函数获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------ | ---- | -------------------- | -| len | number | 是 | 表示生成随机数的长度 | -| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------------- | ---- | ------------------------------------------------------------ | +| key | [DataBlob](#datablob) | 是 | 指定的对称密钥材料。 | +| callback | AsyncCallback\<[SymKey](#symkey)> | 是 | 回调函数。当生成对称密钥成功,err为undefined,data为获取到的SymKey;否则为错误对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17630001 | crypto operation error. | +| 错误码ID | 错误信息 | +| -------- | --------------------------------------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; -var rand; -try { - rand = cryptoFramework.createRandom(); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +function genKeyMaterialBlob() { + let arr = [ + 0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56, + 0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c, + 0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72]; // keyLen = 192 (24 bytes) + let keyMaterial = new Uint8Array(arr); + return {data: keyMaterial}; } -rand.generateRandom(12, (err, randData) => { - if (err) { - console.error("[Callback] err: " + err.code); - } else { - console.error("[Callback]: generate random result: " + randData.data); - } -}); + +let symAlgName = '3DES192'; +let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); +let keyMaterialBlob = genKeyMaterialBlob(); +symKeyGenerator.convertKey(keyMaterialBlob, (err, symKey) => { + if (err) { + console.error(`Convert symKey failed, ${err.code}, ${err.message}`); + } else { + console.info(`Convert symKey success, algName: ${symKey.algName}`); + } +}) ``` -### generateRandom +### convertKey -generateRandom(len : number) : Promise\; +convertKey(key: DataBlob): Promise\ -生成指定长度的随机数 +异步根据指定数据生成对称密钥,通过Promise获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ------ | ---- | -------------------- | -| len | number | 是 | 表示生成随机数的长度 | +| 参数名 | 类型 | 必填 | 说明 | +| ---- | --------------------- | ---- | -------------------- | +| key | [DataBlob](#datablob) | 是 | 指定的密钥材料数据。 | **返回值:** -| 类型 | 说明 | -| ------------------ | ----------- | -| Promise\<[DataBlob](#datablob)> | Promise对象 | +| 类型 | 说明 | +| --------------------------- | --------------------------------- | +| Promise\<[SymKey](#symkey)> | Promise对象,返回对称密钥SymKey。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17630001 | crypto operation error. | - -**示例:** +| 错误码ID | 错误信息 | +| -------- | --------------------------------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +**示例:** -var rand; -try { - rand = cryptoFramework.createRandom(); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; + +function genKeyMaterialBlob() { + let arr = [ + 0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56, + 0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c, + 0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72]; // keyLen = 192 (24 bytes) + let keyMaterial = new Uint8Array(arr); + return {data: keyMaterial}; } -var promiseGenerateRand = rand.generateRandom(12); -promiseGenerateRand.then(randData => { - console.error("[Promise]: rand result: " + randData.data); -}).catch(error => { - console.error("[Promise]: error: " + error.message); -}); +let symAlgName = '3DES192'; +let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); +let keyMaterialBlob = genKeyMaterialBlob(); +symKeyGenerator.convertKey(keyMaterialBlob) +.then(symKey => { + console.info(`Convert symKey success, algName: ${symKey.algName}`); +}, error => { + console.error(`Convert symKey failed, ${error.code}, ${error.message}`); +}) ``` -### setSeed +## cryptoFramework.createAsyKeyGenerator -setSeed(seed : DataBlob) : void; +createAsyKeyGenerator(algName: string): AsyKeyGenerator -设置指定的种子 +通过指定算法名称的字符串,获取相应的非对称密钥生成器实例。
支持的规格详见框架概述“[密钥生成规格](../../security/cryptoFramework-overview.md#密钥生成规格)”一节。 **系统能力:** SystemCapability.Security.CryptoFramework -| 参数名 | 类型 | 必填 | 说明 | -| -------- | --------------------- | ---- | ---------- | -| seed | DataBlob | 是 | 设置的种子 | +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | -------------------------------- | +| algName | string | 是 | 待生成对称密钥生成器的算法名称。 | + +**返回值:** + +| 类型 | 说明 | +| --------------- | ---------------------------- | +| [AsyKeyGenerator](#asykeygenerator) | 返回非对称密钥生成器的对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ----------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | **示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -var rand; -try { - rand = cryptoFramework.createRandom(); -} catch (error) { - console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); -} - -rand.generateRandom(12, (err, randData) => { - if (err) { - console.error("[Callback] err: " + err.code); - } else { - console.error("[Callback]: generate random result: " + randData.data); - try { - rand.setSeed(randData); - } catch (error) { - console.log("setSeed failed, errCode: " + error.code + ", errMsg: " + error.message); - } - } -}); +let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); ``` -## ParamsSpec +## AsyKeyGenerator -加解密参数,在进行对称加解密时需要构造其子类对象,并将子类对象传入[init()](#init-2)方法。
适用于需要iv等参数的对称加解密模式(对于无iv等参数的模式如ECB模式,无需构造,在[init()](#init-2)中传入null即可)。 +非对称密钥生成器。在使用该类的方法前,需要先使用createAsyKeyGenerator()方法构建一个AsyKeyGenerator实例。 + +### 属性 **系统能力:** SystemCapability.Security.CryptoFramework -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ------------------------------------------------------------ | -| algName | string | 是 | 是 | 指明对称加解密参数的算法模式。可选值如下:
- "IvParamsSpec": 适用于CBC\|CTR\|OFB\|CFB模式
- "GcmParamsSpec": 适用于GCM模式
- "CcmParamsSpec": 适用于CCM模式 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | -------------------------------- | +| algName | string | 是 | 否 | 非对称密钥生成器指定的算法名称。 | -> **说明:** -> 由于[init()](#init-2)的params参数是ParamsSpec类型(父类),而实际需要传入具体的子类对象(如IvParamsSpec),因此在构造子类对象时应设置其父类ParamsSpec的algName参数,使算法库在init()时知道传入的是哪种子类对象。 +### generateKeyPair -## IvParamsSpec +generateKeyPair(callback: AsyncCallback\): void -加解密参数[ParamsSpec](#paramsspec)的子类,用于在对称加解密时作为[init()](#init-2)方法的参数。
适用于CBC、CTR、OFB、CFB这些仅使用iv作为参数的加解密模式。 +异步获取非对称密钥生成器随机生成的密钥,通过注册回调函数获取结果。 **系统能力:** SystemCapability.Security.CryptoFramework -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ---- | --------------------- | ---- | ---- | ------------------------------------------------------------ | -| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv。常见取值如下:
- AES的CBC\|CTR\|OFB\|CFB模式:iv长度为16字节
- 3DES的CBC\|OFB\|CFB模式:iv长度为8字节 | +**参数:** -> **说明:** -> 传入[init()](#init-2)方法前需要指定其algName属性(来源于父类[ParamsSpec](#paramsspec))。 +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | ------------------------------ | +| callback | AsyncCallback\<[KeyPair](#keypair)> | 是 | 回调函数,用于获取非对称密钥。 | -## GcmParamsSpec +**错误码:** -加解密参数[ParamsSpec](#paramsspec)的子类,用于在对称加解密时作为[init()](#init-2)方法的参数。
适用于GCM模式。 +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 1763000110+ | crypto operation error. | -**系统能力:** SystemCapability.Security.CryptoFramework +**示例:** -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | --------------------- | ---- | ---- | ------------------------------------------------------------ | -| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv,长度为12字节 | -| aad | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数aad,长度为8字节 | -| authTag | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数authTag,长度为16字节。
采用GCM模式加密时,需要获取[doFinal()](#dofinal-2)输出的[DataBlob](#datablob),取出其末尾16字节作为解密时[init()](#init-2)方法的入参[GcmParamsSpec](#gcmparamsspec)中的的authTag | +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -> **说明:** -> 传入[init()](#init-2)方法前需要指定其algName属性(来源于父类[ParamsSpec](#paramsspec))。 +let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); +asyKeyGenerator.generateKeyPair((err, keyPair) => { + if (err) { + console.error("generateKeyPair: error."); + return; + } + console.info("generateKeyPair: success."); +}) +``` -## CcmParamsSpec -加解密参数[ParamsSpec](#paramsspec)的子类,用于在对称加解密时作为[init()](#init-2)方法的参数。
适用于CCM模式。 +### generateKeyPair -**系统能力:** SystemCapability.Security.CryptoFramework +generateKeyPair(): Promise\ -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | --------------------- | ---- | ---- | ------------------------------------------------------------ | -| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv,长度为7字节 | -| aad | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数aad,长度为8字节 | -| authTag | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数authTag,长度为12字节。
采用CCM模式加密时,需要获取[doFinal()](#dofinal-2)输出的[DataBlob](#datablob),取出其末尾12字节作为解密时[init()](#init-2)方法的入参[CcmParamsSpec](#ccmparamsspec)中的authTag | +异步获取该非对称密钥生成器随机生成的密钥,通过Promise获取结果。 -> **说明:** -> 传入[init()](#init-2)方法前需要指定其algName属性(来源于父类[ParamsSpec](#paramsspec))。 +**系统能力:** SystemCapability.Security.CryptoFramework -## CryptoMode +**返回值:** -表示加解密操作的枚举。 +| 类型 | 说明 | +| ----------------- | --------------------------------- | +| Promise\<[KeyPair](#keypair)> | 使用Promise的方式获取非对称密钥。 | -**系统能力:** SystemCapability.Security.CryptoFramework +**错误码:** -| 名称 | 值 | 说明 | -| ------------ | ---- | ---------------- | -| ENCRYPT_MODE | 0 | 表示进行加密操作 | -| DECRYPT_MODE | 1 | 表示进行解密操作 | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 1763000110+ | crypto operation error. | -## Key +**示例:** -密钥(父类),在运行密码算法(如加解密)时需要提前生成其子类对象,并传入[Cipher](#cipher)实例的[init()](#init-2)方法。
密钥可以通过密钥生成器来生成。 +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -### 属性 +let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); +let keyGenPromise = asyKeyGenerator.generateKeyPair(); +keyGenPromise.then( keyPair => { + console.info("generateKeyPair success."); +}).catch(error => { + console.error("generateKeyPair error."); +}); +``` -**系统能力:** SystemCapability.Security.CryptoFramework +### convertKey -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ---------------------------- | -| format | string | 是 | 否 | 密钥的格式。 | -| algName | string | 是 | 否 | 密钥对应的算法名(含长度)。 | +convertKey(pubKey: DataBlob, priKey: DataBlob, callback: AsyncCallback\): void -### getEncoded +异步获取指定数据生成非对称密钥,通过注册回调函数获取结果。详情请看下方**密钥转换说明**。 -getEncoded() : DataBlob +**系统能力:** SystemCapability.Security.CryptoFramework -以同步方法,获取16进制形式的密钥内容。 +**参数:** -**系统能力:** SystemCapability.Security.CryptoFramework +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------- | ---- | ------------------------------ | +| pubKey | [DataBlob](#datablob) | 是 | 指定的公钥材料。如果公钥不需要转换,可直接传入null。 | +| priKey | [DataBlob](#datablob) | 是 | 指定的私钥材料。如果私钥不需要转换,可直接传入null。 | +| callback | AsyncCallback\<[KeyPair](#keypair)> | 是 | 回调函数,用于获取非对称密钥。 | -**返回值:** +**错误码:** -| 类型 | 说明 | -| --------------------- | ------------------------ | -| [DataBlob](#datablob) | 用于查看密钥的具体内容。 | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 1763000110+ | crypto operation error. | **示例:** -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -function uint8ArrayToShowStr(uint8Array) { - return Array.prototype.map - .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2)) - .join(''); -} -let key; // key为使用对称密钥生成器 生成的密钥,此处省略生成过程 -let encodedKey = key.getEncoded(); -console.info("key hex:" + uint8ArrayToShowStr(encodedKey.data)); +let pubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]); +let priKeyArray = new Uint8Array([48,49,2,1,1,4,32,115,56,137,35,207,0,60,191,90,61,136,105,210,16,27,4,171,57,10,61,123,40,189,28,34,207,236,22,45,223,10,189,160,10,6,8,42,134,72,206,61,3,1,7]); +let pubKeyBlob = { data: pubKeyArray }; // 公钥的密钥数据 +let priKeyBlob = { data: priKeyArray }; // 私钥的密钥数据 +let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); +asyKeyGenerator.convertKey(pubKeyBlob, priKeyBlob, (err, keyPair) => { + if (err) { + console.error("convertKey: error."); + return; + } + console.info("convertKey: success."); +}) ``` -## SymKey +### convertKey -对称密钥,是[Key](#key)的子类,在对称加解密时需要将其对象传入[Cipher](#cipher)实例的[init()](#init-2)方法使用。
对称密钥可以通过对称密钥生成器[SymKeyGenerator](#symkeygenerator)来生成。 +convertKey(pubKey: DataBlob, priKey: DataBlob): Promise\ -### clearMem +异步获取指定数据生成非对称密钥,通过Promise获取结果。详情请看下方**密钥转换说明**。 -clearMem() : void +**系统能力:** SystemCapability.Security.CryptoFramework -以同步方法,将系统底层内存中的的密钥内容清零。建议在不再使用对称密钥实例时,调用本函数,避免内存中密钥数据存留过久。 +**参数:** -**系统能力:** SystemCapability.Security.CryptoFramework +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------------- | +| pubKey | DataBlob | 是 | 指定的公钥材料。如果公钥不需要转换,可直接传入null。 | +| priKey | DataBlob | 是 | 指定的私钥材料。如果私钥不需要转换,可直接传入null。 | -**示例:** +**返回值:** -```js -import cryptoFramework from "@ohos.security.cryptoFramework" -function uint8ArrayToShowStr(uint8Array) { - return Array.prototype.map - .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2)) - .join(''); -} +| 类型 | 说明 | +| ----------------- | --------------------------------- | +| Promise\<[KeyPair](#keypair)> | 使用Promise的方式获取非对称密钥。 | -let key; // key为使用对称密钥生成器 生成的密钥,此处省略生成过程 -let encodedKey = key.getEncoded(); -console.info("key hex:" + uint8ArrayToShowStr(encodedKey.data)); // 输出密钥内容 -key.clearMem(); -encodedKey = key.getEncoded(); -console.info("key hex:" + uint8ArrayToShowStr(encodedKey.data)); // 输出全零 -``` +**错误码:** -## PubKey +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 1763000110+ | crypto operation error. | -公钥,是Key的子类,在非对称加解密、验签、密钥协商时需要将其对象作为输入使用。
公钥可以通过非对称密钥生成器AsyKeyGenerator来生成。 +**示例:** -### 属性 +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -**系统能力:** SystemCapability.Security.CryptoFramework +let pubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]); +let priKeyArray = new Uint8Array([48,49,2,1,1,4,32,115,56,137,35,207,0,60,191,90,61,136,105,210,16,27,4,171,57,10,61,123,40,189,28,34,207,236,22,45,223,10,189,160,10,6,8,42,134,72,206,61,3,1,7]); +let pubKeyBlob = { data: pubKeyArray }; // 公钥的密钥数据 +let priKeyBlob = { data: priKeyArray }; // 私钥的密钥数据 +let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); +let keyGenPromise = asyKeyGenerator.convertKey(pubKeyBlob, priKeyBlob); +keyGenPromise.then( keyPair => { + console.info("convertKey success."); +}).catch(error => { + console.error("convertKey error."); +}); +``` -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ---------------------------- | -| format | string | 是 | 否 | 密钥的格式。 | -| algName | string | 是 | 否 | 密钥对应的算法名(含长度)。 | +**密钥转换说明** +1. 非对称密钥(RSA、ECC、DSA)的公钥和私钥调用getEncoded()方法后,分别返回X.509格式和PKCS#8格式的二进制数据,此数据可用于跨应用传输或持久化存储。 +2. 当调用convertKey方法将外来二进制数据转换为算法库非对称密钥对象时,公钥应满足ASN.1语法、X.509规范、DER编码格式,私钥应满足ASN.1语法、PKCS#8规范、DER编码格式。 +3. convertKey方法中,公钥和密钥二进制数据非必选项,可单独传入公钥或私钥的数据,生成对应只包含公钥或私钥的KeyPair对象。 -### getEncoded +## cryptoFramework.createAsyKeyGeneratorBySpec10+ -getEncoded() : DataBlob +createAsyKeyGeneratorBySpec(asyKeySpec: AsyKeySpec): AsyKeyGeneratorBySpec -以同步方法,获取二进制形式的密钥内容。公钥格式满足ASN.1语法、X.509规范、DER编码格式。 +通过指定密钥参数,获取相应的非对称密钥生成器实例。
支持的规格详见框架概述“[密钥生成规格](../../security/cryptoFramework-overview.md#密钥生成规格)”一节。 **系统能力:** SystemCapability.Security.CryptoFramework +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | -------------------------------- | +| asyKeySpec | [AsyKeySpec](#asykeyspec) | 是 | 密钥参数。非对称密钥生成器根据指定的这些参数生成公/私钥。 | + **返回值:** -| 类型 | 说明 | -| --------------------- | ------------------------ | -| [DataBlob](#datablob) | 用于查看密钥的具体内容。 | +| 类型 | 说明 | +| ----------------------------------------------- | -------------------------- | +| [AsyKeyGeneratorBySpec](#asykeygeneratorbyspec) | 返回非对称密钥生成器实例。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | **示例:** -```js -function uint8ArrayToShowStr(uint8Array) { - return Array.prototype.map - .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2)) - .join(''); +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +// 设置DSA1024中公私钥都包含的公共参数 +function genDsa1024CommonSpecBigE() { + let dsaCommonSpec = { + algName : "DSA", + specType : cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + p : BigInt("0xed1501551b8ab3547f6355ffdc2913856ddeca198833dbd04f020e5f25e47c50e0b3894f7690a0d2ea5ed3a7be25c54292a698e1f086eb3a97deb4dbf04fcad2dafd94a9f35c3ae338ab35477e16981ded6a5b13d5ff20bf55f1b262303ad3a80af71aa6aa2354d20e9c82647664bdb6b333b7bea0a5f49d55ca40bc312a1729"), + q : BigInt("0xd23304044019d5d382cfeabf351636c7ab219694ac845051f60b047b"), + g : BigInt("0x2cc266d8bd33c3009bd67f285a257ba74f0c3a7e12b722864632a0ac3f2c17c91c2f3f67eb2d57071ef47aaa8f8e17a21ad2c1072ee1ce281362aad01dcbcd3876455cd17e1dd55d4ed36fa011db40f0bbb8cba01d066f392b5eaa9404bfcb775f2196a6bc20eeec3db32d54e94d87ecdb7a0310a5a017c5cdb8ac78597778bd"), + } + return dsaCommonSpec; +} +// 设置DSA1024中公私钥包含的全量参数 +function genDsa1024KeyPairSpecBigE() { + let dsaCommonSpec = genDsa1024CommonSpecBigE(); + let dsaKeyPairSpec = { + algName : "DSA", + specType : cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, + params : dsaCommonSpec, + sk : BigInt("0xa2dd2adb2d11392c2541930f61f1165c370aabd2d78d00342e0a2fd9"), + pk : BigInt("0xae6b5d5042e758f3fc9a02d009d896df115811a75b5f7b382d8526270dbb3c029403fafb8573ba4ef0314ea86f09d01e82a14d1ebb67b0c331f41049bd6b1842658b0592e706a5e4d20c14b67977e17df7bdd464cce14b5f13bae6607760fcdf394e0b73ac70aaf141fa4dafd736bd0364b1d6e6c0d7683a5de6b9221e7f2d6b"), + } + return dsaKeyPairSpec; } -let key; // key为使用非对称密钥生成器生成的非对称密钥的公钥对象,此处省略生成过程 -console.info("key format:" + key.format); -console.info("key algName:" + key.algName); -var encodedKey = key.getEncoded(); -console.info("key encoded:" + uint8ArrayToShowStr(encodedKey.data)); +let asyKeyPairSpec = genDsa1024KeyPairSpecBigE(); // JS输入采用大端写法,并使用正数 +let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); ``` -## PriKey +## AsyKeyGeneratorBySpec10+ -私钥,是Key的子类,在非对称加解密、签名、密钥协商时需要将其作为输入使用。
私钥可以通过非对称密钥生成器AsyKeyGenerator来生成。 +非对称密钥生成器。在使用该类的方法前,需要先使用[createAsyKeyGeneratorBySpec()](#cryptoframeworkcreateasykeygeneratorbyspec)方法构建一个AsyKeyGeneratorBySpec实例。 ### 属性 -**系统能力:** SystemCapability.Security.CryptoFramework +**系统能力:** SystemCapability.Security.CryptoFramework -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ---------------------------- | -| format | string | 是 | 否 | 密钥的格式。 | -| algName | string | 是 | 否 | 密钥对应的算法名(含长度)。 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | -------------------------- | +| algName | string | 是 | 否 | 非对称密钥生成器的算法名。 | -### getEncoded +### generateKeyPair -getEncoded() : DataBlob +generateKeyPair(callback: AsyncCallback\): void -以同步方法,获取二进制形式的密钥内容。私钥格式满足ASN.1语法,PKCS#8规范、DER编码方式。 +异步获取非对称密钥生成器生成的密钥,通过注册回调函数获取结果。当使用COMMON_PARAMS_SPEC类型的密钥参数来创建密钥生成器时,可以得到随机生成的密钥对;当使用KEY_PAIR_SPEC类型的密钥参数来创建密钥生成器时,可以得到各项数据与密钥参数一致的密钥对。 **系统能力:** SystemCapability.Security.CryptoFramework -**返回值:** +**参数:** -| 类型 | 说明 | -| --------------------- | ------------------------ | -| [DataBlob](#datablob) | 用于查看密钥的具体内容。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | ------------------------------ | +| callback | AsyncCallback\<[KeyPair](#keypair)> | 是 | 回调函数,用于获取非对称密钥。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ----------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | **示例:** -```js -function uint8ArrayToShowStr(uint8Array) { - return Array.prototype.map - .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2)) - .join(''); -} +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -let key; // key为使用非对称密钥生成器生成的非对称密钥的私钥对象,此处省略生成过程 -console.info("key format:" + key.format); -console.info("key algName:" + key.algName); -var encodedKey = key.getEncoded(); -console.info("key encoded:" + uint8ArrayToShowStr(encodedKey.data)); +let asyKeyPairSpec; // asyKeyPairSpec为全量密钥参数,此处省略生成过程 +let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); +asyKeyGenerator.generateKeyPair((err, keyPair) => { + if (err) { + console.error("generateKeyPair: error."); + return; + } + console.info("generateKeyPair: success."); +}) ``` -### clearMem +### generateKeyPair -clearMem() : void +generateKeyPair(): Promise\ -以同步方法,将系统底层内存中的的密钥内容清零。 +异步获取该非对称密钥生成器生成的密钥,通过Promise获取结果。当使用COMMON_PARAMS_SPEC类型的密钥参数来创建密钥生成器时,可以得到随机生成的密钥对;当使用KEY_PAIR_SPEC类型的密钥参数来创建密钥生成器时,可以得到各项数据与密钥参数一致的密钥对。 **系统能力:** SystemCapability.Security.CryptoFramework -**示例:** - -```js -let key; // key为使用非对称密钥生成器生成的非对称密钥的私钥对象,此处省略生成过程 -key.clearMem(); -``` - -## KeyPair +**返回值:** -非对称密钥对,包含:公钥与私钥。
可以通过非对称密钥生成器AsyKeyGenerator来生成。 +| 类型 | 说明 | +| ----------------- | --------------------------------- | +| Promise\<[KeyPair](#keypair)> | 使用Promise的方式获取非对称密钥。 | -> **说明:** -> -> KeyPair对象中的pubKey对象和priKey对象,作为KeyPair对象中的一个参数存在,当离开KeyPair对象作用域时,其内部对象可能被析构。
业务方使用时应持有KeyPair对象的引用,而非内部pubKey或priKey对象的引用。 +**错误码:** -### 属性 +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | -**系统能力:** SystemCapability.Security.CryptoFramework +**示例:** -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ------------ | -| priKey | [PriKey](#prikey) | 是 | 否 | 私钥。 | -| pubKey | [PubKey](#pubkey) | 是 | 否 | 公钥。 | +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" +let asyKeyPairSpec; // asyKeyPairSpec为全量密钥参数,此处省略生成过程 +let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); +let keyGenPromise = asyKeyGenerator.generateKeyPair(); +keyGenPromise.then( keyPair => { + console.info("generateKeyPair success."); +}).catch(error => { + console.error("generateKeyPair error."); +}); +``` -## cryptoFramework.createSymKeyGenerator +### generatePriKey -createSymKeyGenerator(algName : string) : SymKeyGenerator +generatePriKey(callback: AsyncCallback\): void -通过指定算法名称的字符串,获取相应的对称密钥生成器实例。
支持的规格详见框架概述“[密钥生成规格](../../security/cryptoFramework-overview.md#密钥生成规格)”一节。 +异步获取非对称密钥生成器生成的密钥,通过注册回调函数获取结果。当使用PRIVATE_KEY_SPEC类型的密钥参数来创建密钥生成器时,可以得到指定的私钥;当使用KEY_PAIR_SPEC类型的密钥参数来创建密钥生成器时,可以从生成的密钥对中获取指定的私钥。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------- | ------ | ---- | ------------------------------------------------------------ | -| algName | string | 是 | 待生成对称密钥生成器的算法名称。
具体取值详见框架概述“[密钥生成规格](../../security/cryptoFramework-overview.md#密钥生成规格)”一节中的“字符串参数”。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | ------------------------------ | +| callback | AsyncCallback\<[PriKey](#prikey)> | 是 | 回调函数,用于获取非对称密钥。 | -**返回值:** +**错误码:** -| 类型 | 说明 | -| ----------------------------------- | -------------------------- | -| [SymKeyGenerator](#symkeygenerator) | 返回对称密钥生成器的对象。 | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | **示例:** -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; -let symKeyGenerator = cryptoFramework.createSymKeyGenerator('3DES192'); +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let asyKeyPairSpec; // asyKeyPairSpec为全量密钥参数 +let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); +asyKeyGenerator.generatePriKey((err, prikey) => { + if (err) { + console.error("generatePriKey: error."); + return; + } + console.info("generatePriKey: success."); +}) ``` -## SymKeyGenerator +### generatePriKey -对称密钥生成器。
在使用该类的方法前,需要先使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)方法构建一个symKeyGenerator实例。 +generatePriKey(): Promise\ -### 属性 +异步获取该非对称密钥生成器生成的密钥,通过Promise获取结果。当使用PRIVATE_KEY_SPEC类型的密钥参数来创建密钥生成器时,可以得到指定的私钥;当使用KEY_PAIR_SPEC类型的密钥参数来创建密钥生成器时,可以从生成的密钥对中获取指定的私钥。 **系统能力:** SystemCapability.Security.CryptoFramework -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ------------------------------ | -| algName | string | 是 | 否 | 对称密钥生成器指定的算法名称。 | +**返回值:** -### generateSymKey +| 类型 | 说明 | +| ----------------- | --------------------------------- | +| Promise\<[PriKey](#prikey)> | 使用Promise的方式获取非对称密钥。 | -generateSymKey(callback : AsyncCallback\) : void +**错误码:** -异步获取对称密钥生成器随机生成的密钥,通过注册回调函数获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。
目前支持使用OpenSSL的RAND_priv_bytes()作为底层能力生成随机密钥。 +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | + +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let asyKeyPairSpec; // asyKeyPairSpec为全量密钥参数 +let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); +let keyGenPromise = asyKeyGenerator.generatePriKey(); +keyGenPromise.then( priKey => { + console.info("generatePriKey success."); +}).catch(error => { + console.error("generatePriKey error."); +}); +``` + +### generatePubKey + +generatePubKey(callback: AsyncCallback\): void + +异步获取非对称密钥生成器生成的密钥,通过注册回调函数获取结果。当使用PUBLIC_KEY_SPEC类型的密钥参数来创建密钥生成器时,可以得到指定的公钥;当使用KEY_PAIR_SPEC类型的密钥参数来创建密钥生成器时,可以从生成的密钥对中获取指定的公钥。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | --------------------------------- | ---- | ------------------------------------------------------------ | -| callback | AsyncCallback\<[SymKey](#symkey)> | 是 | 回调函数。当生成对称密钥成功,err为undefined,data为获取到的SymKey;否则为错误对象。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | ------------------------------ | +| callback | AsyncCallback\<[PubKey](#pubkey)> | 是 | 回调函数,用于获取非对称密钥。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | **示例:** -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; -let symAlgName = '3DES192'; -let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); -symKeyGenerator.generateSymKey((err, symKey) => { +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let asyKeyPairSpec; // asyKeyPairSpec为全量密钥参数,此处省略生成过程 +let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); +asyKeyGenerator.generateKeyPair((err, pubKey) => { if (err) { - console.error(`Generate symKey failed, ${err.code}, ${err.message}`); - } else { - console.info(`Generate symKey success, algName: ${symKey.algName}`); + console.error("generatePubKey: error."); + return; } + console.info("generatePubKey: success."); }) ``` -### generateSymKey +### generatePubKey -generateSymKey() : Promise\ +generatePubKey(): Promise\ -异步获取该对称密钥生成器随机生成的密钥,通过Promise获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。
目前支持使用OpenSSL的RAND_priv_bytes()作为底层能力生成随机密钥。 +异步获取该非对称密钥生成器生成的密钥,通过Promise获取结果。当使用PUBLIC_KEY_SPEC类型的密钥参数来创建密钥生成器时,可以得到指定的公钥;当使用KEY_PAIR_SPEC类型的密钥参数来创建密钥生成器时,可以从生成的密钥对中获取指定的公钥。 **系统能力:** SystemCapability.Security.CryptoFramework **返回值:** -| 类型 | 说明 | -| --------------------------- | --------------------------------- | -| Promise\<[SymKey](#symkey)> | Promise对象,返回对称密钥SymKey。 | +| 类型 | 说明 | +| ----------------- | --------------------------------- | +| Promise\<[PubKey](#pubkey)> | 使用Promise的方式获取非对称密钥。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | **示例:** -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; -let symAlgName = 'AES128'; -let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); -symKeyGenerator.generateSymKey() -.then(symKey => { - console.info(`Generate symKey success, algName: ${symKey.algName}`); -}, error => { - console.error(`Generate symKey failed, ${error.code}, ${error.message}`); -}) +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let asyKeyPairSpec; // asyKeyPairSpec为全量密钥参数,此处省略生成过程 +let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); +let keyGenPromise = asyKeyGenerator.generatePubKey(); +keyGenPromise.then( pubKey => { + console.info("generatePubKey success."); +}).catch(error => { + console.error("generatePubKey error."); +}); ``` -### convertKey +## cryptoFramework.createCipher -convertKey(key : DataBlob, callback : AsyncCallback\) : void +createCipher(transformation: string): Cipher -异步根据指定数据生成对称密钥,通过注册回调函数获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。 +通过指定算法名称,获取相应的[Cipher](#cipher)实例。
支持的规格详见框架概述“[加解密规格](../../security/cryptoFramework-overview.md#加解密规格)”一节。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | --------------------------------- | ---- | ------------------------------------------------------------ | -| key | [DataBlob](#datablob) | 是 | 指定的对称密钥材料。 | -| callback | AsyncCallback\<[SymKey](#symkey)> | 是 | 回调函数。当生成对称密钥成功,err为undefined,data为获取到的SymKey;否则为错误对象。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------------- | ------ | ---- | ------------------------------------------------------------ | +| transformation | string | 是 | 待生成Cipher的算法名称(含密钥长度)、加密模式以及填充方法的组合。
具体取值详见框架概述“[加解密规格](../../security/cryptoFramework-overview.md#加解密规格)”一节中的“字符串参数”。 | + +> **说明:** +> 1. 目前对称加解密中,PKCS5和PKCS7的实现相同,其padding长度和分组长度保持一致(即PKCS5和PKCS7在3DES中均按照8字节填充,在AES中均按照16字节填充),另有NoPadding表示不填充。
开发者需要自行了解密码学不同分组模式的差异,以便选择合适的参数规格。例如选择ECB和CBC模式时,建议启用填充,否则必须确保明文长度是分组大小的整数倍;选择其他模式时,可以不启用填充,此时密文长度和明文长度一致(即可能不是分组大小的整数倍)。 +> 2. 使用RSA进行非对称加解密时,必须创建两个Cipher对象分别进行加密和解密操作,而不能对同一个Cipher对象进行加解密。对称加解密没有此要求(即只要算法规格一样,可以对同一个Cipher对象进行加解密操作)。 + +**返回值:** + +| 类型 | 说明 | +| ----------------- | ------------------------ | +| [Cipher](#cipher) | 返回加解密生成器的对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | --------------------------------------------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 1762000110+ | memory error. | **示例:** -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -function genKeyMaterialBlob() { - let arr = [ - 0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56, - 0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c, - 0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72]; // keyLen = 192 (24 bytes) - let keyMaterial = new Uint8Array(arr); - return {data : keyMaterial}; +let cipherAlgName = '3DES192|ECB|PKCS7'; +var cipher; +try { + cipher = cryptoFramework.createCipher(cipherAlgName); + console.info(`cipher algName: ${cipher.algName}`); +} catch (error) { + console.error(`createCipher failed, ${error.code}, ${error.message}`); } +``` -let symAlgName = '3DES192'; -let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); -let keyMaterialBlob = genKeyMaterialBlob(); -symKeyGenerator.convertKey(keyMaterialBlob, (err, symKey) => { - if (err) { - console.error(`Convert symKey failed, ${err.code}, ${err.message}`); - } else { - console.info(`Convert symKey success, algName: ${symKey.algName}`); - } -}) -``` +## Cipher -### convertKey +提供加解密的算法操作功能,按序调用本类中的[init()](#init-2)、[update()](#update-4)、[doFinal()](#dofinal-2)方法,可以实现对称加密/对称解密/非对称加密/非对称解密。
完整的加解密流程示例可参考开发指导中的“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”一节。 -convertKey(key : DataBlob) : Promise\ +一次完整的加/解密流程在对称加密和非对称加密中略有不同: -异步根据指定数据生成对称密钥,通过Promise获取结果。
必须在使用[createSymKeyGenerator](#cryptoframeworkcreatesymkeygenerator)创建对称密钥生成器后,才能使用本函数。 +- 对称加解密:init为必选,update为可选(且允许多次update加/解密大数据),doFinal为必选;doFinal结束后可以重新init开始新一轮加/解密流程。 +- RSA非对称加解密:init为必选,不支持update操作,doFinal为必选(允许连续多次doFinal加/解密大数据);RSA不支持重复init,切换加解密模式或填充方式时,需要重新创建Cipher对象。 + +### 属性 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---- | --------------------- | ---- | -------------------- | -| key | [DataBlob](#datablob) | 是 | 指定的密钥材料数据。 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------------- | +| algName | string | 是 | 否 | 加解密生成器指定的算法名称。 | -**返回值:** +### init -| 类型 | 说明 | -| --------------------------- | --------------------------------- | -| Promise\<[SymKey](#symkey)> | Promise对象,返回对称密钥SymKey。 | +init(opMode: CryptoMode, key: Key, params: ParamsSpec, callback: AsyncCallback\): void + +初始化加解密的[cipher](#cipher)对象,通过注册回调函数获取结果。
必须在使用[createCipher](#cryptoframeworkcreatecipher)创建[Cipher](#cipher)实例后,才能使用本函数。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------- | ---- | ------------------------------------------------------------ | +| opMode | [CryptoMode](#cryptomode) | 是 | 加密或者解密模式。 | +| key | [Key](#key) | 是 | 指定加密或解密的密钥。 | +| params | [ParamsSpec](#paramsspec) | 是 | 指定加密或解密的参数,对于ECB等没有参数的算法模式,可以传入null。 | +| callback | AsyncCallback\ | 是 | 回调函数。当初始化成功,err为undefined,否则为错误对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | --------------------------------------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | --------------------------------------------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error.| **示例:** ```js import cryptoFramework from '@ohos.security.cryptoFramework'; +let symKey; // 此处省略生成对称密钥的过程 +let cipher; // 此处省略生成cipher实例的过程 -function genKeyMaterialBlob() { - let arr = [ - 0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56, - 0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c, - 0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72]; // keyLen = 192 (24 bytes) - let keyMaterial = new Uint8Array(arr); - return {data : keyMaterial}; -} - -let symAlgName = '3DES192'; -let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName); -let keyMaterialBlob = genKeyMaterialBlob(); -symKeyGenerator.convertKey(keyMaterialBlob) -.then(symKey => { - console.info(`Convert symKey success, algName: ${symKey.algName}`); -}, error => { - console.error(`Convert symKey failed, ${error.code}, ${error.message}`); +cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null, (err, ) => { + if (err) { + console.error(`Failed to init cipher, ${err.code}, ${err.message}`); + } else { + console.info(`Init cipher success`); + // 此处进行update等后续操作 + } }) ``` -## cryptoFramework.createAsyKeyGenerator +### init -createAsyKeyGenerator(algName : string) : AsyKeyGenerator +init(opMode: CryptoMode, key: Key, params: ParamsSpec): Promise\ -通过指定算法名称的字符串,获取相应的非对称密钥生成器实例。
支持的规格详见框架概述“[密钥生成规格](../../security/cryptoFramework-overview.md#密钥生成规格)”一节。 +初始化加解密的cipher对象,通过Promise获取结果。
必须在使用[createCipher](#cryptoframeworkcreatecipher)创建[Cipher](#cipher)实例后,才能使用本函数。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------- | ------ | ---- | -------------------------------- | -| algName | string | 是 | 待生成对称密钥生成器的算法名称。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------------------------- | ---- | ------------------------------------------------------------ | +| opMode | [CryptoMode](#cryptomode) | 是 | 加密或者解密模式。 | +| key | [Key](#key) | 是 | 指定加密或解密的密钥。 | +| params | [ParamsSpec](#paramsspec) | 是 | 指定加密或解密的参数,对于ECB等没有参数的算法模式,可以传入null。 | **返回值:** -| 类型 | 说明 | -| --------------- | ---------------------------- | -| [AsyKeyGenerator](#asykeygenerator) | 返回非对称密钥生成器的对象。 | - -**示例:** - -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" - -let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); -``` +| 类型 | 说明 | +| -------------- | -------------------------------------- | +| Promise\ | Promise对象。无返回结果的Promise对象。 | -## AsyKeyGenerator +**错误码:** -非对称密钥生成器。在使用该类的方法前,需要先使用createAsyKeyGenerator()方法构建一个AsyKeyGenerator实例。 +| 错误码ID | 错误信息 | +| -------- | ------------------------------------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error.| -### 属性 +**示例:** -**系统能力:** SystemCapability.Security.CryptoFramework +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; +let symKey; // 此处省略生成对称密钥的过程 +let cipher; // 此处省略生成cipher实例的过程 +cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null) +.then(() => { + console.info(`Init cipher success`); + // 此处进行update等后续操作 +}, error => { + console.error(`Failed to init cipher, ${error.code}, ${error.message}`); +}) +``` -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | -------------------------------- | -| algName | string | 是 | 否 | 非对称密钥生成器指定的算法名称。 | +### update -### generateKeyPair +update(data: DataBlob, callback: AsyncCallback\): void -generateKeyPair(callback : AsyncCallback\) : void; +分段更新加密或者解密数据操作,通过注册回调函数获取加/解密数据。
必须在对[Cipher](#cipher)实例使用[init()](init-2)初始化后,才能使用本函数。 -异步获取非对称密钥生成器随机生成的密钥,通过注册回调函数获取结果。 +> **说明:** +> 1. 在进行对称加解密操作的时候,如果开发者对各个分组模式不够熟悉,建议对每次update和doFinal的结果都判断是否为null,并在结果不为null时取出其中的数据进行拼接,形成完整的密文/明文。这是因为选择的分组模式等各项规格都可能对update和[doFinal](#dofinal-2)结果产生影响。
(例如对于ECB和CBC模式,不论update传入的数据是否为分组长度的整数倍,都会以分组作为基本单位进行加/解密,并输出本次update新产生的加/解密分组结果。
可以理解为,update只要凑满一个新的分组就会有输出,如果没有凑满则此次update输出为null,把当前还没被加/解密的数据留着,等下一次update/doFinal传入数据的时候,拼接起来继续凑分组。
最后doFinal的时候,会把剩下的还没加/解密的数据,根据[createCipher](#cryptoframeworkcreatecipher)时设置的padding模式进行填充,补齐到分组的整数倍长度,再输出剩余加解密结果。
而对于可以将分组密码转化为流模式实现的模式,还可能出现密文长度和明文长度相同的情况等。) +> 2. 根据数据量,可以不调用update(即[init](#init-2)完成后直接调用[doFinal](#dofinal-2))或多次调用update。
算法库目前没有对update(单次或累计)的数据量设置大小限制,建议对于大数据量的对称加解密,采用多次update的方式传入数据。
AES使用多次update操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 +> 3. RSA非对称加解密不支持update操作。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ----------------------- | ---- | ------------------------------ | -| callback | AsyncCallback\<[KeyPair](#keypair)> | 是 | 回调函数,用于获取非对称密钥。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------- | ---- | ------------------------------------------------------------ | +| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。data不能为null,也不允许传入{data: Uint8Array(空) }。 | +| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数。当更新加/解密数据成功,err为undefined,data为此次更新的加/解密结果DataBlob;否则为错误对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | ------------------------------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; -let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); -asyKeyGenerator.generateKeyPair((err, keyPair) => { +function stringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); +} + +let cipher; // 此处省略生成cipher实例的过程 +// 此处省略init()过程 +let plainText = {data: stringToUint8Array('this is test!')}; +cipher.update(plainText, (err, output) => { // 加密过程举例 if (err) { - console.error("generateKeyPair: error."); - return; + console.error(`Failed to update cipher`); + } else { + console.info(`Update cipher success`); + if (output != null) { + // 拼接output.data到密文 + } + // 此处进行doFinal等后续操作 } - console.info("generateKeyPair: success."); }) ``` +### update -### generateKeyPair +update(data: DataBlob): Promise\ -generateKeyPair() : Promise\ +分段更新加密或者解密数据操作,通过通过Promise获取加/解密数据。
必须在对[Cipher](#cipher)实例使用[init()](init-2)初始化后,才能使用本函数。 -异步获取该非对称密钥生成器随机生成的密钥,通过Promise获取结果。 +> **说明:** +> 1. 在进行对称加解密操作的时候,如果开发者对各个分组模式不够熟悉,建议对每次update和doFinal的结果都判断是否为null,并在结果不为null时取出其中的数据进行拼接,形成完整的密文/明文。这是因为选择的分组模式等各项规格都可能对update和[doFinal](#dofinal-2)结果产生影响。
(例如对于ECB和CBC模式,不论update传入的数据是否为分组长度的整数倍,都会以分组作为基本单位进行加/解密,并输出本次update新产生的加/解密分组结果。
可以理解为,update只要凑满一个新的分组就会有输出,如果没有凑满则此次update输出为null,把当前还没被加/解密的数据留着,等下一次update/doFinal传入数据的时候,拼接起来继续凑分组。
最后doFinal的时候,会把剩下的还没加/解密的数据,根据[createCipher](#cryptoframeworkcreatecipher)时设置的padding模式进行填充,补齐到分组的整数倍长度,再输出剩余加解密结果。
而对于可以将分组密码转化为流模式实现的模式,还可能出现密文长度和明文长度相同的情况等。) +> 2. 根据数据量,可以不调用update(即[init](#init-2)完成后直接调用[doFinal](#dofinal-2))或多次调用update。
算法库目前没有对update(单次或累计)的数据量设置大小限制,建议对于大数据量的对称加解密,可以采用多次update的方式传入数据。
AES使用多次update操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 +> 3. RSA非对称加解密不支持update操作。 **系统能力:** SystemCapability.Security.CryptoFramework +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---- | --------------------- | ---- | -------------------- | +| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。data不能为null,也不允许传入{data: Uint8Array(空) }。 | + **返回值:** -| 类型 | 说明 | -| ----------------- | --------------------------------- | -| Promise\<[KeyPair](#keypair)> | 使用Promise的方式获取非对称密钥。 | +| 类型 | 说明 | +| ------------------------------- | ------------------------------------------------ | +| Promise\<[DataBlob](#datablob)> | Promise对象,返回此次更新的加/解密结果DataBlob。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | -------------------------------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; -let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); -let keyGenPromise = asyKeyGenerator.generateKeyPair(); -keyGenPromise.then( keyPair => { - console.info("generateKeyPair success."); -}).catch(error => { - console.error("generateKeyPair error."); -}); +function stringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); +} + +let cipher; // 此处省略生成cipher实例的过程 +// 此处省略init()过程 +let plainText = {data: stringToUint8Array('this is test!')}; +cipher.update(plainText) +.then((output) => { + console.info(`Update cipher success.`); + if (output != null) { + // 拼接output.data到密文 + } + // 此处进行doFinal等后续操作 +}, error => { + console.info(`Update cipher failed.`); +}) ``` -### convertKey +### doFinal -convertKey(pubKey : DataBlob, priKey : DataBlob, callback : AsyncCallback\) : void +doFinal(data: DataBlob, callback: AsyncCallback\): void -异步获取指定数据生成非对称密钥,通过注册回调函数获取结果。详情请看下方**密钥转换说明** +(1)在对称加解密中,doFinal加/解密(分组模式产生的)剩余数据和本次传入的数据,最后结束加密或者解密数据操作,通过注册回调函数获取加密或者解密数据。
如果数据量较小,可以在doFinal中一次性传入数据,而不使用update;如果在本次加解密流程中,已经使用[update](#update-4)传入过数据,可以在doFinal的data参数处传入null。
根据对称加解密的模式不同,doFinal的输出有如下区别: -**系统能力:** SystemCapability.Security.CryptoFramework +- 对于GCM和CCM模式的对称加密:一次加密流程中,如果将每一次update和doFinal的结果拼接起来,会得到“密文+authTag”,即末尾的16字节(GCM模式)或12字节(CCM模式)是authTag,而其余部分均为密文。(也就是说,如果doFinal的data参数传入null,则doFinal的结果就是authTag)
authTag需要填入解密时的[GcmParamsSpec](#gcmparamsspec)或[CcmParamsSpec](#ccmparamsspec);密文则作为解密时的入参data。 +- 对于其他模式的对称加解密、GCM和CCM模式的对称解密:一次加/解密流程中,每一次update和doFinal的结果拼接起来,得到完整的明文/密文。 -**参数:** +(2)在RSA非对称加解密中,doFinal加/解密本次传入的数据,通过注册回调函数获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。 -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ----------- | ---- | ------------------------------ | -| pubKey | [DataBlob](#datablob) | 是 | 指定的公钥材料。如果公钥不需要转换,可直接传入null。 | -| priKey | [DataBlob](#datablob) | 是 | 指定的私钥材料。如果私钥不需要转换,可直接传入null。 | -| callback | AsyncCallback\<[KeyPair](#keypair)> | 是 | 回调函数,用于获取非对称密钥。 | +> **说明:** +> 1. 对称加解密中,调用doFinal标志着一次加解密流程已经完成,即[Cipher](#cipher)实例的状态被清除,因此当后续开启新一轮加解密流程时,需要重新调用[init()](init-2)并传入完整的参数列表进行初始化
(比如即使是对同一个Cipher实例,采用同样的对称密钥,进行加密然后解密,则解密中调用init的时候仍需填写params参数,而不能直接省略为null)。 +> 2. 如果遇到解密失败,需检查加解密数据和[init](#init-2)时的参数是否匹配,包括GCM模式下加密得到的authTag是否填入解密时的GcmParamsSpec等。 +> 3. doFinal的结果可能为null,因此使用.data字段访问doFinal结果的具体数据前,请记得先判断结果是否为null,避免产生异常。 +> 4. RSA非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 -**错误码:** +**系统能力:** SystemCapability.Security.CryptoFramework -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------- | ---- | ------------------------------------------------------------ | +| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。在对称加解密中允许为null,但不允许传入{data: Uint8Array(空) }。 | +| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数。当最终加/解密数据成功,err为undefined,data为剩余数据的加/解密结果DataBlob;否则为错误对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ----------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" -let pubKey; // X.509规范、DER格式的公钥数据,此处省略数据。 -let priKey; // PKCS#8规范、DER格式的私钥数据,此处省略数据。 -let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); -asyKeyGenerator.convertKey(pubKey, priKey, (err, keyPair) => { +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; + +let cipher; // 此处省略生成cipher实例的过程 +let data; // 此处省略准备待加密/解密数据的过程 +// 此处省略init()和update()过程 +cipher.doFinal(data, (err, output) => { if (err) { - console.error("convertKey: error."); - return; + console.error(`Failed to finalize cipher, ${err.code}, ${err.message}`); + } else { + console.info(`Finalize cipher success`); + if (output != null) { + // 拼接output.data得到完整的明文/密文(及authTag) + } } - console.info("convertKey: success."); }) ``` -### convertKey +### doFinal + +doFinal(data: DataBlob): Promise\ + +(1)在对称加解密中,doFinal加/解密(分组模式产生的)剩余数据和本次传入的数据,最后结束加密或者解密数据操作,通过Promise获取加密或者解密数据。
如果数据量较小,可以在doFinal中一次性传入数据,而不使用update;如果在本次加解密流程中,已经使用[update](#update-4)传入过数据,可以在doFinal的data参数处传入null。
根据对称加解密的模式不同,doFinal的输出有如下区别: -convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\ +- 对于GCM和CCM模式的对称加密:一次加密流程中,如果将每一次update和doFinal的结果拼接起来,会得到“密文+authTag”,即末尾的16字节(GCM模式)或12字节(CCM模式)是authTag,而其余部分均为密文。(也就是说,如果doFinal的data参数传入null,则doFinal的结果就是authTag)
authTag需要填入解密时的[GcmParamsSpec](#gcmparamsspec)或[CcmParamsSpec](#ccmparamsspec);密文则作为解密时的入参data。 +- 对于其他模式的对称加解密、GCM和CCM模式的对称解密:一次加/解密流程中,每一次update和doFinal的结果拼接起来,得到完整的明文/密文。 + +(2)在RSA非对称加解密中,doFinal加/解密本次传入的数据,通过Promise获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。 -异步获取指定数据生成非对称密钥,通过Promise获取结果。详情请看下方**密钥转换说明** +> **说明:** +> 1. 对称加解密中,调用doFinal标志着一次加解密流程已经完成,即[Cipher](#cipher)实例的状态被清除,因此当后续开启新一轮加解密流程时,需要重新调用[init()](init-2)并传入完整的参数列表进行初始化
(比如即使是对同一个Cipher实例,采用同样的对称密钥,进行加密然后解密,则解密中调用init的时候仍需填写params参数,而不能直接省略为null)。 +> 2. 如果遇到解密失败,需检查加解密数据和[init](#init-2)时的参数是否匹配,包括GCM模式下加密得到的authTag是否填入解密时的GcmParamsSpec等。 +> 3. doFinal的结果可能为null,因此使用.data字段访问doFinal结果的具体数据前,请记得先判断结果是否为null,避免产生异常。 +> 4. RSA非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | -------- | ---- | ---------------- | -| pubKey | DataBlob | 是 | 指定的公钥材料。如果公钥不需要转换,可直接传入null | -| priKey | DataBlob | 是 | 指定的私钥材料。如果私钥不需要转换,可直接传入null | +| 参数名 | 类型 | 必填 | 说明 | +| ---- | --------------------- | ---- | -------------------- | +| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。data参数允许为null,但不允许传入{data: Uint8Array(空) }。 | **返回值:** -| 类型 | 说明 | -| ----------------- | --------------------------------- | -| Promise\<[KeyPair](#keypair)> | 使用Promise的方式获取非对称密钥。 | +| 类型 | 说明 | +| ------------------------------- | ------------------------------------------------ | +| Promise\<[DataBlob](#datablob)> | Promise对象,返回剩余数据的加/解密结果DataBlob。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | -------------------------------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | **示例:** -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +```js +import cryptoFramework from '@ohos.security.cryptoFramework'; -let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); -let pubKey; // pubKey为使用非对称密钥生成器生成的非对称密钥的公钥对象,此处省略生成过程 -let priKey; // priKey为使用非对称密钥生成器生成的非对称密钥的私钥对象,此处省略生成过程 -let keyGenPromise = asyKeyGenerator.convertKey(pubKey, priKey); -keyGenPromise.then( keyPair => { - console.info("convertKey success."); -}).catch(error => { - console.error("convertKey error."); -}); +let cipher; // 此处省略生成cipher实例的过程 +let data; // 此处省略准备待加密/解密数据的过程 +// 此处省略init()和update()过程 +cipher.doFinal(data) +.then(output => { + console.info(`Finalize cipher success`); + if (output != null) { + // 拼接output.data得到完整的明文/密文(及authTag) + } +}, error => { + console.error(`Failed to finalize cipher, ${error.code}, ${error.message}`); +}) ``` -**密钥转换说明** - -1. 非对称密钥(RSA、ECC)的公钥和私钥调用getEncoded()方法后,分别返回X.509格式和PKCS#8格式的二进制数据,此数据可用于跨应用传输或持久化存储。 -2. 当调用convertKey方法将外来二进制数据转换为算法库非对称密钥对象时,公钥应满足ASN.1语法、X.509规范、DER编码格式,私钥应满足ASN.1语法、PKCS#8规范、DER编码格式。 -3. convertKey方法中,公钥和密钥二进制数据非必选项,可单独传入公钥或私钥的数据,生成对应只包含公钥或私钥的KeyPair对象。 - -## cryptoFramework.createCipher - -createCipher(transformation : string) : Cipher - -通过指定算法名称,获取相应的[Cipher](#cipher)实例。
支持的规格详见框架概述“[加解密规格](../../security/cryptoFramework-overview.md#加解密规格)”一节。 - -**系统能力:** SystemCapability.Security.CryptoFramework - -**参数:** - -| 参数名 | 类型 | 必填 | 说明 | -| -------------- | ------ | ---- | ------------------------------------------------------------ | -| transformation | string | 是 | 待生成Cipher的算法名称(含密钥长度)、加密模式以及填充方法的组合。
具体取值详见框架概述“[加解密规格](../../security/cryptoFramework-overview.md#加解密规格)”一节中的“字符串参数”。 | - -> **说明:** -> 1. 目前对称加解密中,PKCS5和PKCS7的实现相同,其padding长度和分组长度保持一致(即PKCS5和PKCS7在3DES中均按照8字节填充,在AES中均按照16字节填充),另有NoPadding表示不填充。
开发者需要自行了解密码学不同分组模式的差异,以便选择合适的参数规格。例如选择ECB和CBC模式时,建议启用填充,否则必须确保明文长度是分组大小的整数倍;选择其他模式时,可以不启用填充,此时密文长度和明文长度一致(即可能不是分组大小的整数倍)。 -> 2. 使用RSA进行非对称加解密时,必须创建两个Cipher对象分别进行加密和解密操作,而不能对同一个Cipher对象进行加解密。对称加解密没有此要求(即只要算法规格一样,可以对同一个Cipher对象进行加解密操作)。 - -**返回值:** - -| 类型 | 说明 | -| ----------------- | ------------------------ | -| [Cipher](#cipher) | 返回加解密生成器的对象。 | - -**示例:** +**使用RSA加密的callback完整示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -let cipherAlgName = '3DES192|ECB|PKCS7'; -var cipher; -try { - cipher = cryptoFramework.createCipher(cipherAlgName); - console.info(`cipher algName: ${cipher.algName}`); -} catch (error) { - console.error(`createCipher failed, ${error.code}, ${error.message}`); +function stringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); } -``` - -## Cipher - -提供加解密的算法操作功能,按序调用本类中的[init()](#init-2)、[update()](#update-4)、[doFinal()](#dofinal-2)方法,可以实现对称加密/对称解密/非对称加密/非对称解密。
完整的加解密流程示例可参考开发指导中的“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”一节。 -一次完整的加/解密流程在对称加密和非对称加密中略有不同: +let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); +let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); +rsaGenerator.generateKeyPair(function (err, keyPair) { + let pubKey = keyPair.pubKey; + cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null, function (err, data) { + let plainText = "this is cipher text"; + let input = {data: stringToUint8Array(plainText) }; + cipher.doFinal(input, function (err, data) { + AlertDialog.show({ message: "EncryptOutPut is " + data.data} ); + }); + }); +}); +``` -- 对称加解密:init为必选,update为可选(且允许多次update加/解密大数据),doFinal为必选;doFinal结束后可以重新init开始新一轮加/解密流程。 -- RSA非对称加解密:init为必选,不支持update操作,doFinal为必选(允许连续多次doFinal加/解密大数据);RSA不支持重复init,切换加解密模式或填充方式时,需要重新创建Cipher对象。 +**使用RSA加密的promise完整示例:** -### 属性 +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -**系统能力:** SystemCapability.Security.CryptoFramework +function stringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); +} +let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); +let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); +let keyGenPromise = rsaGenerator.generateKeyPair(); +keyGenPromise.then(rsaKeyPair => { + let pubKey = rsaKeyPair.pubKey; + return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null); // 传入私钥和DECRYPT_MODE可初始化解密模式 +}).then(() => { + let plainText = "this is cipher text"; + let input = { data: stringToUint8Array(plainText) }; + return cipher.doFinal(input); +}).then(dataBlob => { + console.info("EncryptOutPut is " + dataBlob.data); +}); +``` -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ---------------------------- | -| algName | string | 是 | 否 | 加解密生成器指定的算法名称。 | +> **说明:** +> 更多加解密流程的完整示例可参考开发指导中的“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”一节。 -### init +### setCipherSpec10+ -init(opMode : CryptoMode, key : Key, params : ParamsSpec, callback : AsyncCallback\) : void +setCipherSpec(itemType: CipherSpecItem, itemValue: Uint8Array): void -初始化加解密的[cipher](#cipher)对象,通过注册回调函数获取结果。
必须在使用[createCipher](#cryptoframeworkcreatecipher)创建[Cipher](#cipher)实例后,才能使用本函数。 +设置加解密参数。常用的加解密参数可以直接通过[createCipher](#cryptoframeworkcreatecipher) 来指定,剩余参数可以通过本接口指定。当前只支持RSA算法。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------- | ---- | ------------------------------------------------------------ | -| opMode | [CryptoMode](#cryptomode) | 是 | 加密或者解密模式。 | -| key | [Key](#key) | 是 | 指定加密或解密的密钥。 | -| params | [ParamsSpec](#paramsspec) | 是 | 指定加密或解密的参数,对于ECB等没有参数的算法模式,可以传入null。 | -| callback | AsyncCallback\ | 是 | 回调函数。当初始化成功,err为undefined,否则为错误对象。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------- | +| itemType | [CipherSpecItem](#cipherspecitem) | 是 | 用于指定需要设置的加解密参数。 | +| itemValue | Uint8Array | 是 | 用于指定加解密参数的具体值。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | --------------------------------------------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error.| +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | **示例:** -```js +```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; -let symKey; // 此处省略生成对称密钥的过程 -let cipher; // 此处省略生成cipher实例的过程 -cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null, (err, ) => { - if (err) { - console.error(`Failed to init cipher, ${err.code}, ${err.message}`); - } else { - console.info(`Init cipher success`); - // 此处进行update等后续操作 - } -}) +let cipher; // 此处省略生成Cipher实例的过程 +let pSource = new Uint8Array([1,2,3,4]); +cipher.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource); ``` -### init +### getCipherSpec10+ -init(opMode : CryptoMode, key : Key, params : ParamsSpec) : Promise\ +getCipherSpec(itemType: CipherSpecItem): string | Uint8Array -初始化加解密的cipher对象,通过Promise获取结果。
必须在使用[createCipher](#cryptoframeworkcreatecipher)创建[Cipher](#cipher)实例后,才能使用本函数。 +获取加解密参数。当前只支持RSA算法。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ------------------------- | ---- | ------------------------------------------------------------ | -| opMode | [CryptoMode](#cryptomode) | 是 | 加密或者解密模式。 | -| key | [Key](#key) | 是 | 指定加密或解密的密钥。 | -| params | [ParamsSpec](#paramsspec) | 是 | 指定加密或解密的参数,对于ECB等没有参数的算法模式,可以传入null。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------- | +| itemType | [CipherSpecItem](#cipherspecitem) | 是 | 用于指定需要获取的加解密参数。 | **返回值:** -| 类型 | 说明 | -| -------------- | -------------------------------------- | -| Promise\ | Promise对象。无返回结果的Promise对象。 | +| 类型 | 说明 | +| -------------- | ----------- | +| string\|Uint8Array | 获取的加解密参数的具体值。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ------------------------------------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error.| +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | **示例:** -```js +```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; -let symKey; // 此处省略生成对称密钥的过程 -let cipher; // 此处省略生成cipher实例的过程 -cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null) -.then(() => { - console.info(`Init cipher success`); - // 此处进行update等后续操作 -}, error => { - console.error(`Failed to init cipher, ${error.code}, ${error.message}`); -}) -``` -### update +let cipher; // 此处省略生成Cipher实例的过程 +let md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR); +``` -update(data : DataBlob, callback : AsyncCallback\) : void +## cryptoFramework.createSign -分段更新加密或者解密数据操作,通过注册回调函数获取加/解密数据。
必须在对[Cipher](#cipher)实例使用[init()](init-2)初始化后,才能使用本函数。 +createSign(algName: string): Sign -> **说明:** -> 1. 在进行对称加解密操作的时候,如果开发者对各个分组模式不够熟悉,建议对每次update和doFinal的结果都判断是否为null,并在结果不为null时取出其中的数据进行拼接,形成完整的密文/明文。这是因为选择的分组模式等各项规格都可能对update和[doFinal](#dofinal-2)结果产生影响。
(例如对于ECB和CBC模式,不论update传入的数据是否为分组长度的整数倍,都会以分组作为基本单位进行加/解密,并输出本次update新产生的加/解密分组结果。
可以理解为,update只要凑满一个新的分组就会有输出,如果没有凑满则此次update输出为null,把当前还没被加/解密的数据留着,等下一次update/doFinal传入数据的时候,拼接起来继续凑分组。
最后doFinal的时候,会把剩下的还没加/解密的数据,根据[createCipher](#cryptoframeworkcreatecipher)时设置的padding模式进行填充,补齐到分组的整数倍长度,再输出剩余加解密结果。
而对于可以将分组密码转化为流模式实现的模式,还可能出现密文长度和明文长度相同的情况等。) -> 2. 根据数据量,可以不调用update(即[init](#init-2)完成后直接调用[doFinal](#dofinal-2))或多次调用update。
算法库目前没有对update(单次或累计)的数据量设置大小限制,建议对于大数据量的对称加解密,采用多次update的方式传入数据。
AES使用多次update操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 -> 3. RSA非对称加解密不支持update操作。 +Sign实例生成。
支持的规格详见框架概述“[签名验签规格](../../security/cryptoFramework-overview.md#签名验签规格)”一节。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------------------- | ---- | ------------------------------------------------------------ | -| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。data不能为null,也不允许传入{data : Uint8Array(空) } | -| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数。当更新加/解密数据成功,err为undefined,data为此次更新的加/解密结果DataBlob;否则为错误对象。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | ------------------------------------------------------------ | +| algName | string | 是 | 指定签名算法:RSA或ECC,使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要。 | + +**返回值**: + +| 类型 | 说明 | +| ---- | ---------------------------------- | +| Sign | 返回由输入算法指定生成的Sign对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ------------------------------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error. | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 80110+ | this operation is not supported. | +| 1762000110+ | memory error. | **示例:** -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -function stringToUint8Array(str) { - let arr = []; - for (let i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - return new Uint8Array(arr); -} +let signer1 = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); -let cipher; // 此处省略生成cipher实例的过程 -// 此处省略init()过程 -let plainText = {data : stringToUint8Array('this is test!')}; -cipher.update(plainText, (err, output) => { // 加密过程举例 - if (err) { - console.error(`Failed to update cipher`); - } else { - console.info(`Update cipher success`); - if (output != null) { - // 拼接output.data到密文 - } - // 此处进行doFinal等后续操作 - } -}) +let singer2 = cryptoFramework.createSign("RSA1024|PSS|SHA256|MGF1_SHA256") ``` +## Sign + +Sign类,使用Sign方法之前需要创建该类的实例进行操作,通过createSign(algName: string): Sign方法构造此实例。Sign类不支持重复初始化,当业务方需要使用新密钥签名时,需要重新创建新Sign对象并调用init初始化。 + +业务方使用时,在createSign时确定签名的模式,调用init接口设置密钥。 + +当待签名数据较短时,可在init初始化后直接调用sign接口传入原文数据进行签名。 + +当待签名数据较长时,可通过update接口分段传入切分后的原文数据,最后调用sign接口对整体原文数据进行签名。 + +当使用update分段传入原文时,sign接口支持传null,业务方可在循环中调用update接口,循环结束后调用sign进行签名。 + +### 属性 + +**系统能力:** SystemCapability.Security.CryptoFramework + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------------- | +| algName | string | 是 | 否 | 签名指定的算法名称。 | + +### init + +init(priKey: PriKey, callback: AsyncCallback\): void + +使用私钥初始化Sign对象,Callback形式,Sign类暂不支持重复init。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------------- | +| priKey | [PriKey](#prikey) | 是 | 用于Sign的初始化。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### init + +init(priKey: PriKey): Promise\ + +使用私钥初始化Sign对象,Promise形式,Sign类暂不支持重复init。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ---- | ---- | ---------------- | +| priKey | [PriKey](#prikey) | 是 | 用于Sign的初始化。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + ### update -update(data : DataBlob) : Promise\ +update(data: DataBlob, callback: AsyncCallback\): void -分段更新加密或者解密数据操作,通过通过Promise获取加/解密数据。
必须在对[Cipher](#cipher)实例使用[init()](init-2)初始化后,才能使用本函数。 +追加待签名数据,callback方式。 > **说明:** -> 1. 在进行对称加解密操作的时候,如果开发者对各个分组模式不够熟悉,建议对每次update和doFinal的结果都判断是否为null,并在结果不为null时取出其中的数据进行拼接,形成完整的密文/明文。这是因为选择的分组模式等各项规格都可能对update和[doFinal](#dofinal-2)结果产生影响。
(例如对于ECB和CBC模式,不论update传入的数据是否为分组长度的整数倍,都会以分组作为基本单位进行加/解密,并输出本次update新产生的加/解密分组结果。
可以理解为,update只要凑满一个新的分组就会有输出,如果没有凑满则此次update输出为null,把当前还没被加/解密的数据留着,等下一次update/doFinal传入数据的时候,拼接起来继续凑分组。
最后doFinal的时候,会把剩下的还没加/解密的数据,根据[createCipher](#cryptoframeworkcreatecipher)时设置的padding模式进行填充,补齐到分组的整数倍长度,再输出剩余加解密结果。
而对于可以将分组密码转化为流模式实现的模式,还可能出现密文长度和明文长度相同的情况等。) -> 2. 根据数据量,可以不调用update(即[init](#init-2)完成后直接调用[doFinal](#dofinal-2))或多次调用update。
算法库目前没有对update(单次或累计)的数据量设置大小限制,建议对于大数据量的对称加解密,可以采用多次update的方式传入数据。
AES使用多次update操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 -> 3. RSA非对称加解密不支持update操作。 +> Sign多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---- | --------------------- | ---- | -------------------- | -| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。data不能为null,也不允许传入{data : Uint8Array(空) } | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------- | ---- | ------------ | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### update + +update(data: DataBlob): Promise\ + +追加待签名数据,promise方式。 + +> **说明:** +> Sign多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------- | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### sign + +sign(data: DataBlob, callback: AsyncCallback\): void + +对数据进行签名,返回签名结果,callback方式。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------- | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | +| callback | AsyncCallback\<[DataBlob](#datablob) > | 是 | 回调函数。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### sign + +sign(data: DataBlob): Promise\ + +对数据进行签名,返回签名结果,promise方式。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------- | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +**callback示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +function stringToUint8Array(str) { + var arr = []; + for (var i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + var tmpArray = new Uint8Array(arr); + return tmpArray; +} + +let globalKeyPair; +let SignMessageBlob; +let plan1 = "This is Sign test plan1"; // The first segment of data. +let plan2 = "This is Sign test plan2"; // The second segment of fata. +let input1 = { data: stringToUint8Array(plan1) }; +let input2 = { data: stringToUint8Array(plan2) }; + +function signMessageCallback() { + let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); + let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); + rsaGenerator.generateKeyPair(function (err, keyPair) { + globalKeyPair = keyPair; + let priKey = globalKeyPair.priKey; + signer.init(priKey, function (err, data) { + signer.update(input1, function (err, data) { // add first segment of data + signer.sign(input2, function (err, data) { // add second segment of data, sign input1 and input2 + SignMessageBlob = data; + AlertDialog.show({message: "res" + SignMessageBlob.data}); + }); + }); + }); + }); +} +``` + +**promise示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +function stringToUint8Array(str) { + var arr = []; + for (var i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + var tmpArray = new Uint8Array(arr); + return tmpArray; +} + +let globalKeyPair; +let SignMessageBlob; +let plan1 = "This is Sign test plan1"; // The first segment of data. +let plan2 = "This is Sign test plan2"; // The second segment of fata. +let input1 = { data: stringToUint8Array(plan1) }; +let input2 = { data: stringToUint8Array(plan2) }; + +function signMessagePromise() { + let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); + let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); + let keyGenPromise = rsaGenerator.generateKeyPair(); + keyGenPromise.then( keyPair => { + globalKeyPair = keyPair; + let priKey = globalKeyPair.priKey; + return signer.init(priKey); + }).then(() => { + return signer.update(input1); // add first segment of data + }).then(() => { + return signer.sign(input2); // add second segment of data, sign input1 and input2 + }).then(dataBlob => { + SignMessageBlob = dataBlob; + console.info("sign output is " + SignMessageBlob.data); + AlertDialog.show({message: "output" + SignMessageBlob.data}); + }); +} +``` + +### setSignSpec10+ + +setSignSpec(itemType: SignSpecItem, itemValue: number): void + +设置签名参数。常用的签名参数可以直接通过[createSign](#cryptoframeworkcreatesign) 来指定,剩余参数可以通过本接口指定。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------- | +| itemType | [SignSpecItem](#signspecitem) | 是 | 用于指定需要设置的签名参数。 | +| itemValue | number | 是 | 用于指定签名参数的具体值。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | + +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let signer; // 此处省略生成Sign实例的过程 +let setN = 20; +signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN); +``` + +### getSignSpec10+ + +getSignSpec(itemType: SignSpecItem): string | number + +获取签名参数。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------- | +| itemType | [SignSpecItem](#signspecitem) | 是 | 用于指定需要获取的签名参数。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ----------- | +| string\|number | 获取的签名参数的具体值。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | + +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let signer; // 此处省略生成Sign实例的过程 +let saltLen = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); +``` + +## cryptoFramework.createVerify + +createVerify(algName: string): Verify + +Verify实例生成。
支持的规格详见框架概述“[签名验签规格](../../security/cryptoFramework-overview.md#签名验签规格)”一节。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | ------------------------------------------------------------ | +| algName | string | 是 | 指定签名算法:RSA或ECC,使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要。 | + +**返回值**: + +| 类型 | 说明 | +| ------ | ------------------------------------ | +| Verify | 返回由输入算法指定生成的Verify对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 80110+ | this operation is not supported. | +| 1762000110+ | memory error. | + +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let verifyer1 = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256"); + +let verifyer2 = cryptoFramework.createVerify("RSA1024|PSS|SHA256|MGF1_SHA256") +``` + +## Verify + +Verify类,使用Verify方法之前需要创建该类的实例进行操作,通过createVerify(algName: string): Verify方法构造此实例。 + +Verify类不支持重复初始化,当业务方需要使用新密钥验签时,需要重新创建新Verify对象并调用init初始化。 + +业务方使用时,在createVerify时确定验签的模式,调用init接口设置密钥。 + +当签名数据较短时,可在init初始化后直接调用verify接口传入签名数据和原文进行验签。 + +当签名数据较长时,可通过update接口分段传入签名数据,最后调用verify接口对整体签名数据进行验签。 + +当使用update分段传入签名数据时,verify接口的签名数据支持传null,业务方可在循环中调用update接口,循环结束后调用verify传入原文进行验签。 + +### 属性 + +**系统能力:** SystemCapability.Security.CryptoFramework + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------------- | +| algName | string | 是 | 否 | 验签指定的算法名称。 | + + + +### init + +init(pubKey: PubKey, callback: AsyncCallback\): void + +传入公钥初始化Verify对象,Callback形式 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ------------------------------ | +| pubKey | [PubKey](#pubkey) | 是 | 公钥对象,用于Verify的初始化。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### init + +init(pubKey: PubKey): Promise\ + +传入公钥初始化Verify对象,Promise形式。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ---- | ---- | ---------------------------- | +| pubKey | [PubKey](#pubkey) | 是 | 公钥对象,用于Verify的初始化。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### update + +update(data: DataBlob, callback: AsyncCallback\): void + +追加待验签数据,callback方式。 + +> **说明:** +> Verify多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------- | ---- | ------------ | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### update + +update(data: DataBlob): Promise\ + +追加待验签数据,promise方式。 + +> **说明:** +> Verify多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------- | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### verify + +verify(data: DataBlob, signatureData: DataBlob, callback: AsyncCallback\): void + +对数据进行验签,返回验签结果,callback方式。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------- | -------------------- | ---- | ---------- | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | +| signatureData | [DataBlob](#datablob) | 是 | 签名数据。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +### verify + +verify(data: DataBlob, signatureData: DataBlob): Promise\ + +对数据进行验签,返回验签结果,promise方式。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------- | -------- | ---- | ---------- | +| data | [DataBlob](#datablob) | 是 | 传入的消息。 | +| signatureData | [DataBlob](#datablob) | 是 | 签名数据。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------- | ------------------------------ | +| Promise\ | 异步返回值,代表验签是否通过。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | + +**callback示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 +let input1 = null; +let input2 = null; +let signMessageBlob = null; // 签名后的数据,此处省略 +let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA25"); +verifyer.init(globalKeyPair.pubKey, function (err, data) { + verifyer.update(input1, function(err, data) { + verifyer.verify(input2, signMessageBlob, function(err, data) { + console.info("verify result is " + data); + }) + }); +}) +``` + +**promise示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 +let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256"); +let verifyInitPromise = verifyer.init(globalKeyPair.pubKey); +let input1 = null; +let input2 = null; +let signMessageBlob = null; // 签名后的数据,此处省略 +verifyInitPromise.then(() => { + return verifyer.update(input1); +}).then(() => { + return verifyer.verify(input2, signMessageBlob); +}).then(res => { + console.log("Verify result is " + res); +}); +``` + +### setVerifySpec10+ + +setVerifySpec(itemType: SignSpecItem, itemValue: number): void + +设置验签参数。常用的签名参数可以直接通过[createVerify](#cryptoframeworkcreateverify) 来指定,剩余参数可以通过本接口指定。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------- | +| itemType | [SignSpecItem](#signspecitem) | 是 | 用于指定需要设置的验签参数。 | +| itemValue | number | 是 | 用于指定验签参数的具体值。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | + +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let verifyer; // 此处省略生成Verify实例的过程 +let setN = 20; +verifyer.setVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN); +``` + +### getVerifySpec10+ + +getVerifySpec(itemType: SignSpecItem): string | number + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------- | +| itemType | [SignSpecItem](#signspecitem) | 是 | 用于指定需要获取的验签参数。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ----------- | +| string\|number | 获取的验签参数的具体值。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 801 | this operation is not supported. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | + +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let verifyer; // 此处省略生成Verify实例的过程 +let saltLen = verifyer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); +``` + +## cryptoFramework.createKeyAgreement + +createKeyAgreement(algName: string): KeyAgreement + +KeyAgreement实例生成。
支持的规格详见框架概述“[密钥协商规格](../../security/cryptoFramework-overview.md#密钥协商规格)”一节。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | --------------------------------- | +| algName | string | 是 | 指定密钥协商算法:目前仅支持ECC。 | -**返回值:** +**返回值**: -| 类型 | 说明 | -| ------------------------------- | ------------------------------------------------ | -| Promise\<[DataBlob](#datablob)> | Promise对象,返回此次更新的加/解密结果DataBlob。 | +| 类型 | 说明 | +| ------------ | ------------------------------------------ | +| KeyAgreement | 返回由输入算法指定生成的KeyAgreement对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | -------------------------------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error. | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 80110+ | this operation is not supported. | +| 1762000110+ | memory error. | **示例:** -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -function stringToUint8Array(str) { - let arr = []; - for (let i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - return new Uint8Array(arr); -} +let keyAgreement = cryptoFramework.createKeyAgreement("ECC256"); -let cipher; // 此处省略生成cipher实例的过程 -// 此处省略init()过程 -let plainText = {data : stringToUint8Array('this is test!')}; -cipher.update(plainText) -.then((output) => { - console.info(`Update cipher success.`); - if (output != null) { - // 拼接output.data到密文 - } - // 此处进行doFinal等后续操作 -}, error => { - console.info(`Update cipher failed.`); -}) ``` -### doFinal +## KeyAgreement -doFinal(data : DataBlob, callback : AsyncCallback\) : void +KeyAgreement类,使用密钥协商方法之前需要创建该类的实例进行操作,通过createKeyAgreement(algName: string): KeyAgreement方法构造此实例。 -(1)在对称加解密中,doFinal加/解密(分组模式产生的)剩余数据和本次传入的数据,最后结束加密或者解密数据操作,通过注册回调函数获取加密或者解密数据。
如果数据量较小,可以在doFinal中一次性传入数据,而不使用update;如果在本次加解密流程中,已经使用[update](#update-4)传入过数据,可以在doFinal的data参数处传入null。
根据对称加解密的模式不同,doFinal的输出有如下区别: +### 属性 -- 对于GCM和CCM模式的对称加密:一次加密流程中,如果将每一次update和doFinal的结果拼接起来,会得到“密文+authTag”,即末尾的16字节(GCM模式)或12字节(CCM模式)是authTag,而其余部分均为密文。(也就是说,如果doFinal的data参数传入null,则doFinal的结果就是authTag)
authTag需要填入解密时的[GcmParamsSpec](#gcmparamsspec)或[CcmParamsSpec](#ccmparamsspec);密文则作为解密时的入参data。 -- 对于其他模式的对称加解密、GCM和CCM模式的对称解密:一次加/解密流程中,每一次update和doFinal的结果拼接起来,得到完整的明文/密文。 +**系统能力:** SystemCapability.Security.CryptoFramework -(2)在RSA非对称加解密中,doFinal加/解密本次传入的数据,通过注册回调函数获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。 +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------------- | +| algName | string | 是 | 否 | 密钥协商指定的算法名称。 | -> **说明:** -> 1. 对称加解密中,调用doFinal标志着一次加解密流程已经完成,即[Cipher](#cipher)实例的状态被清除,因此当后续开启新一轮加解密流程时,需要重新调用[init()](init-2)并传入完整的参数列表进行初始化
(比如即使是对同一个Cipher实例,采用同样的对称密钥,进行加密然后解密,则解密中调用init的时候仍需填写params参数,而不能直接省略为null)。 -> 2. 如果遇到解密失败,需检查加解密数据和[init](#init-2)时的参数是否匹配,包括GCM模式下加密得到的authTag是否填入解密时的GcmParamsSpec等。 -> 3. doFinal的结果可能为null,因此使用.data字段访问doFinal结果的具体数据前,请记得先判断结果是否为null,避免产生异常。 -> 4. RSA非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 +### generateSecret + +generateSecret(priKey: PriKey, pubKey: PubKey, callback: AsyncCallback\): void + +基于传入的私钥与公钥进行密钥协商,返回共享秘密,Callback形式。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------------------- | ---- | ------------------------------------------------------------ | -| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。在对称加解密中允许为null,但不允许传入{data : Uint8Array(空) }。 | -| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数。当最终加/解密数据成功,err为undefined,data为剩余数据的加/解密结果DataBlob;否则为错误对象。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------ | ---- | ---------------------- | +| priKey | [PriKey](#prikey) | 是 | 设置密钥协商的私钥输入。 | +| pubKey | [PubKey](#pubkey) | 是 | 设置密钥协商的公钥输入。 | +| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 异步接受共享秘密的回调。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ----------------------- | -| 17620001 | memory error. | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | | 17620002 | runtime error. | | 17630001 | crypto operation error. | -**示例:** - -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; - -let cipher; // 此处省略生成cipher实例的过程 -let data; // 此处省略准备待加密/解密数据的过程 -// 此处省略init()和update()过程 -cipher.doFinal(data, (err, output) => { - if (err) { - console.error(`Failed to finalize cipher, ${err.code}, ${err.message}`); - } else { - console.info(`Finalize cipher success`); - if (output != null) { - // 拼接output.data得到完整的明文/密文(及authTag) - } - } -}) -``` - -### doFinal - -doFinal(data : DataBlob) : Promise\ - -(1)在对称加解密中,doFinal加/解密(分组模式产生的)剩余数据和本次传入的数据,最后结束加密或者解密数据操作,通过Promise获取加密或者解密数据。
如果数据量较小,可以在doFinal中一次性传入数据,而不使用update;如果在本次加解密流程中,已经使用[update](#update-4)传入过数据,可以在doFinal的data参数处传入null。
根据对称加解密的模式不同,doFinal的输出有如下区别: - -- 对于GCM和CCM模式的对称加密:一次加密流程中,如果将每一次update和doFinal的结果拼接起来,会得到“密文+authTag”,即末尾的16字节(GCM模式)或12字节(CCM模式)是authTag,而其余部分均为密文。(也就是说,如果doFinal的data参数传入null,则doFinal的结果就是authTag)
authTag需要填入解密时的[GcmParamsSpec](#gcmparamsspec)或[CcmParamsSpec](#ccmparamsspec);密文则作为解密时的入参data。 -- 对于其他模式的对称加解密、GCM和CCM模式的对称解密:一次加/解密流程中,每一次update和doFinal的结果拼接起来,得到完整的明文/密文。 +### generateSecret -(2)在RSA非对称加解密中,doFinal加/解密本次传入的数据,通过Promise获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。 +generateSecret(priKey: PriKey, pubKey: PubKey): Promise\ -> **说明:** -> 1. 对称加解密中,调用doFinal标志着一次加解密流程已经完成,即[Cipher](#cipher)实例的状态被清除,因此当后续开启新一轮加解密流程时,需要重新调用[init()](init-2)并传入完整的参数列表进行初始化
(比如即使是对同一个Cipher实例,采用同样的对称密钥,进行加密然后解密,则解密中调用init的时候仍需填写params参数,而不能直接省略为null)。 -> 2. 如果遇到解密失败,需检查加解密数据和[init](#init-2)时的参数是否匹配,包括GCM模式下加密得到的authTag是否填入解密时的GcmParamsSpec等。 -> 3. doFinal的结果可能为null,因此使用.data字段访问doFinal结果的具体数据前,请记得先判断结果是否为null,避免产生异常。 -> 4. RSA非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。 +基于传入的私钥与公钥进行密钥协商,返回共享秘密,Promise形式。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---- | --------------------- | ---- | -------------------- | -| data | [DataBlob](#datablob) | 是 | 加密或者解密的数据。data参数允许为null,但不允许传入{data : Uint8Array(空) } | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------------- | +| priKey | [PriKey](#prikey) | 是 | 设置密钥协商的私钥输入。 | +| pubKey | [PubKey](#pubkey) | 是 | 设置密钥协商的公钥输入。 | **返回值:** -| 类型 | 说明 | -| ------------------------------- | ------------------------------------------------ | -| Promise\<[DataBlob](#datablob)> | Promise对象,返回剩余数据的加/解密结果DataBlob。 | +| 类型 | 说明 | +| ------------------ | -------- | +| Promise\<[DataBlob](#datablob)> | 共享秘密。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | -------------------------------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error. | - -**示例:** - -```js -import cryptoFramework from '@ohos.security.cryptoFramework'; - -let cipher; // 此处省略生成cipher实例的过程 -let data; // 此处省略准备待加密/解密数据的过程 -// 此处省略init()和update()过程 -cipher.doFinal(data) -.then(output => { - console.info(`Finalize cipher success`); - if (output != null) { - // 拼接output.data得到完整的明文/密文(及authTag) - } -}, error => { - console.error(`Failed to finalize cipher, ${error.code}, ${error.message}`); -}) -``` +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17620002 | runtime error. | +| 17630001 | crypto operation error. | -**使用RSA加密的callback完整示例:** +**callback示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -function stringToUint8Array(str) { - let arr = []; - for (let i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); +let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 +let keyAgreement = cryptoFramework.createKeyAgreement("ECC256"); +keyAgreement.generateSecret(globalKeyPair.priKey, globalKeyPair.pubKey, function (err, secret) { + if (err) { + console.error("keyAgreement error."); + return; } - return new Uint8Array(arr); -} - -let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); -let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); -rsaGenerator.generateKeyPair(function (err, keyPair) { - let pubKey = keyPair.pubKey; - cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null, function (err, data) { - let plainText = "this is cipher text"; - let input = {data : stringToUint8Array(plainText) }; - cipher.doFinal(input, function (err, data) { - AlertDialog.show({ message : "EncryptOutPut is " + data.data} ); - }); - }); + console.info("keyAgreement output is " + secret.data); }); ``` -**使用RSA加密的promise完整示例:** +**promise示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -function stringToUint8Array(str) { - let arr = []; - for (let i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - return new Uint8Array(arr); -} - -let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); -let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); -let keyGenPromise = rsaGenerator.generateKeyPair(); -keyGenPromise.then(rsaKeyPair => { - let pubKey = rsaKeyPair.pubKey; - return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null); // 传入私钥和DECRYPT_MODE可初始化解密模式 -}).then(() => { - let plainText = "this is cipher text"; - let input = { data : stringToUint8Array(plainText) }; - return cipher.doFinal(input); -}).then(dataBlob => { - console.info("EncryptOutPut is " + dataBlob.data); +let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 +let keyAgreement = cryptoFramework.createKeyAgreement("ECC256"); +let keyAgreementPromise = keyAgreement.generateSecret(globalKeyPair.priKey, globalKeyPair.pubKey); +keyAgreementPromise.then((secret) => { + console.info("keyAgreement output is " + secret.data); +}).catch((error) => { + console.error("keyAgreement error."); }); ``` -> **说明:** -> 更多加解密流程的完整示例可参考开发指导中的“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”一节。 - -## cryptoFramework.createSign +## cryptoFramework.createMd -createSign(algName : string) : Sign +createMd(algName: string): Md -Sign实例生成。
支持的规格详见框架概述“[签名验签规格](../../security/cryptoFramework-overview.md#签名验签规格)”一节。 +生成Md实例,用于进行消息摘要的计算与操作。
支持的规格详见框架概述“[MD消息摘要算法规格](../../security/cryptoFramework-overview.md#md消息摘要算法规格)”一节。 **系统能力:** SystemCapability.Security.CryptoFramework @@ -2028,658 +2653,941 @@ Sign实例生成。
支持的规格详见框架概述“[签名验签规格] | 参数名 | 类型 | 必填 | 说明 | | ------- | ------ | ---- | ------------------------------------------------------------ | -| algName | string | 是 | 指定签名算法:RSA或ECC,使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要 | +| algName | string | 是 | 指定摘要算法,支持算法请参考“[MD算法支持范围](../../security/cryptoFramework-overview.md#md消息摘要算法规格)”一节。 | **返回值**: -| 类型 | 说明 | -| ---- | -------------------------------- | -| Sign | 返回由输入算法指定生成的Sign对象 | +| 类型 | 说明 | +| ---- | --------------------------------------- | +| Md | 返回由输入算法指定生成的[Md](#md)对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ------------------ | +| 401 | invalid parameters. | +| 17620001 | memory error. | **示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -let signer1 = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); - -let singer2 = cryptoFramework.createSign("RSA1024|PSS|SHA256|MGF1_SHA256") +var md; +try { + // 参数选择请参考上述算法支持范围 + md = cryptoFramework.createMd("SHA256"); +} catch (error) { + console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +} ``` -## Sign +## Md -Sign类,使用Sign方法之前需要创建该类的实例进行操作,通过createSign(algName : string) : Sign方法构造此实例。Sign类不支持重复初始化,当业务方需要使用新密钥签名时,需要重新创建新Sign对象并调用init初始化。 +Md类,调用Md方法可以进行MD(Message Digest)摘要计算。调用前,需要通过[createMd](#cryptoframeworkcreatemd)构造Md实例。 -业务方使用时,在createSign时确定签名的模式,调用init接口设置密钥。 +### 属性 -当待签名数据较短时,可在init初始化后直接调用sign接口传入原文数据进行签名。 +**系统能力:** SystemCapability.Security.CryptoFramework -当待签名数据较长时,可通过update接口分段传入切分后的原文数据,最后调用sign接口对整体原文数据进行签名。 +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------- | +| algName | string | 是 | 否 | 代表指定的摘要算法名。 | -当使用update分段传入原文时,sign接口支持传null,业务方可在循环中调用update接口,循环结束后调用sign进行签名。 +### update -### 属性 +update(input: DataBlob, callback: AsyncCallback\): void + +传入消息进行Md更新计算。 + +> **说明:** +> Md算法多次调用update更新的代码示例详见开发指导“[使用摘要操作](../../security/cryptoFramework-guidelines.md#使用摘要操作)”。 **系统能力:** SystemCapability.Security.CryptoFramework -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ---------------------------- | -| algName | string | 是 | 否 | 签名指定的算法名称。 | +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------- | ---- | ------------ | +| input | [DataBlob](#datablob) | 是 | 传入的消息。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17630001 | crypto operation error. | + +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +var md; +try { + md = cryptoFramework.createMd("SHA256"); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Md algName is: " + md.algName); + +let blob; +md.update(blob, (err,) => { + if (err) { + console.error("[Callback] err: " + err.code); + } +}); +``` + +### update -### init +update(input: DataBlob): Promise\ -init(priKey : PriKey, callback : AsyncCallback\) : void +传入消息进行Md更新计算。 -使用私钥初始化Sign对象,Callback形式,Sign类暂不支持重复init +> **说明:** +> Md算法多次调用update更新的代码示例详见开发指导“[使用摘要操作](../../security/cryptoFramework-guidelines.md#使用摘要操作)”。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ------------ | +| input | DataBlob | 是 | 传入的消息。 | -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------------- | -| priKey | [PriKey](#prikey) | 是 | 用于Sign的初始化 | -| callback | AsyncCallback\ | 是 | 回调函数 | +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 401 | invalid parameters. | | 17630001 | crypto operation error. | -### init +**示例:** -init(priKey : PriKey) : Promise\ +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -使用私钥初始化Sign对象,Promise形式,Sign类暂不支持重复init +var md; +try { + md = cryptoFramework.createMd("SHA256"); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Md algName is: " + md.algName); -**系统能力:** SystemCapability.Security.CryptoFramework +let blob; +var promiseMdUpdate = md.update(blob); +promiseMdUpdate.then(() => { + // do something +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); +``` -**参数:** +### digest -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ---- | ---- | ---------------- | -| priKey | [PriKey](#prikey) | 是 | 用于Sign的初始化 | +digest(callback: AsyncCallback\): void -**返回值:** +返回Md的计算结果。 -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +**系统能力:** SystemCapability.Security.CryptoFramework + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------ | ---- | ---------- | +| callback | AsyncCallback\ | 是 | 回调函数。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | -### update +**示例:** -update(data : DataBlob, callback : AsyncCallback\) : void +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -追加待签名数据,callback方式 +var md; +try { + md = cryptoFramework.createMd("SHA256"); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Md algName is: " + md.algName); -> **说明:** -> Sign多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 +let blob; +md.update(blob, (err,) => { + if (err) { + console.error("[Callback] err: " + err.code); + } + md.digest((err1, mdOutput) => { + if (err1) { + console.error("[Callback] err: " + err1.code); + } else { + console.error("[Callback]: MD result: " + mdOutput); + } + }); +}); +``` + +### digest + +digest(): Promise\ + +返回Md的计算结果。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** +**返回值:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------- | -| data | [DataBlob](#datablob)| 是 | 传入的消息 | -| callback | AsyncCallback\ | 是 | 回调函数 | +| 类型 | 说明 | +| ------------------ | ----------- | +| Promise\<[DataBlob](#datablob)> | Promise对象。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | -### update +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -update(data : DataBlob) : Promise\; +var md; +try { + md = cryptoFramework.createMd("SHA256"); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Md algName is: " + md.algName); -追加待签名数据,promise方式 +let blob; +var promiseMdUpdate = md.update(blob); +promiseMdUpdate.then(() => { + var PromiseMdDigest = md.digest(); + return PromiseMdDigest; +}).then(mdOutput => { + console.error("[Promise]: MD result: " + mdOutput.data); +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); +``` -> **说明:** -> Sign多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 +### getMdLength -**系统能力:** SystemCapability.Security.CryptoFramework +getMdLength(): number -**参数:** +获取Md消息摘要长度(字节数)。 -| 参数名 | 类型 | 必填 | 说明 | -| ------ | -------- | ---- | ---------- | -| data | [DataBlob](#datablob) | 是 | 传入的消息 | +**系统能力:** SystemCapability.Security.CryptoFramework **返回值:** -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +| 类型 | 说明 | +| ------ | -------------------------- | +| number | 返回md计算结果的字节长度。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | | 17630001 | crypto operation error. | -### sign - -sign(data : DataBlob, callback : AsyncCallback\) : void - -对数据进行签名,返回签名结果,callback方式 - -**系统能力:** SystemCapability.Security.CryptoFramework - -**参数:** +**示例:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------- | -| data | [DataBlob](#datablob) | 是 | 传入的消息 | -| callback | AsyncCallback\<[DataBlob](#datablob) > | 是 | 回调函数 | +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -**错误码:** +var md; +try { + md = cryptoFramework.createMd("SHA256"); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Md algName is: " + md.algName); -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error. | +let blob; +var promiseMdUpdate = md.update(blob); +promiseMdUpdate.then(() => { + var PromiseMdDigest = md.digest(); + return PromiseMdDigest; +}).then(mdOutput => { + console.error("[Promise]: MD result: " + mdOutput.data); + let mdLen = md.getMdLength(); + console.error("MD len: " + mdLen); +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); +``` -### sign +## cryptoFramework.createMac -sign(data : DataBlob) : Promise\ +createMac(algName: string): Mac -对数据进行签名,返回签名结果,promise方式 +生成Mac实例,用于进行消息认证码的计算与操作。
支持的规格详见框架概述“[HMAC消息认证码算法规格](../../security/cryptoFramework-overview.md#hmac消息认证码算法规格)”一节。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | -------- | ---- | ---------- | -| data | [DataBlob](#datablob) | 是 | 传入的消息 | +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | ------------------------------------------------------------ | +| algName | string | 是 | 指定摘要算法,支持算法请参考“[HMAC算法支持范围](../../security/cryptoFramework-overview.md#hmac消息认证码算法规格)”一节。 | -**返回值:** +**返回值**: -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +| 类型 | 说明 | +| ---- | ----------------------------------------- | +| Mac | 返回由输入算法指定生成的[Mac](#mac)对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error. | +| 错误码ID | 错误信息 | +| -------- | ------------------ | +| 401 | invalid parameters. | +| 17620001 | memory error. | -**callback示例:** +**示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - var tmpArray = new Uint8Array(arr); - return tmpArray; -} - -let globalKeyPair; -let SignMessageBlob; -let plan1 = "This is Sign test plan1"; // The first segment of data. -let plan2 = "This is Sign test plan2"; // The second segment of fata. -let input1 = { data : stringToUint8Array(plan1) }; -let input2 = { data : stringToUint8Array(plan2) }; - -function signMessageCallback() { - let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); - let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); - rsaGenerator.generateKeyPair(function (err, keyPair) { - globalKeyPair = keyPair; - let priKey = globalKeyPair.priKey; - signer.init(priKey, function (err, data) { - signer.update(input1, function (err, data) { // add first segment of data - signer.sign(input2, function (err, data) { // add second segment of data, sign input1 and input2 - SignMessageBlob = data; - AlertDialog.show({message : "res" + SignMessageBlob.data}); - }); - }); - }); - }); +var mac; +try { + // 参数选择请参考上述算法支持范围 + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); } ``` -**promise示例:** +## Mac -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +Mac类,调用Mac方法可以进行MAC(Message Authentication Code)加密计算。调用前,需要通过[createMac](#cryptoframeworkcreatemac)构造Mac实例。 -function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - var tmpArray = new Uint8Array(arr); - return tmpArray; -} +### 属性 -let globalKeyPair; -let SignMessageBlob; -let plan1 = "This is Sign test plan1"; // The first segment of data. -let plan2 = "This is Sign test plan2"; // The second segment of fata. -let input1 = { data : stringToUint8Array(plan1) }; -let input2 = { data : stringToUint8Array(plan2) }; +**系统能力:** SystemCapability.Security.CryptoFramework -function signMessagePromise() { - let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); - let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); - let keyGenPromise = rsaGenerator.generateKeyPair(); - keyGenPromise.then( keyPair => { - globalKeyPair = keyPair; - let priKey = globalKeyPair.priKey; - return signer.init(priKey); - }).then(() => { - return signer.update(input1); // add first segment of data - }).then(() => { - return signer.sign(input2); // add second segment of data, sign input1 and input2 - }).then(dataBlob => { - SignMessageBlob = dataBlob; - console.info("sign output is " + SignMessageBlob.data); - AlertDialog.show({message : "output" + SignMessageBlob.data}); - }); -} -``` +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | ---------------------- | +| algName | string | 是 | 否 | 代表指定的摘要算法名。 | -## cryptoFramework.createVerify +### init -createVerify(algName : string) : Verify +init(key: SymKey, callback: AsyncCallback\): void -Verify实例生成。
支持的规格详见框架概述“[签名验签规格](../../security/cryptoFramework-overview.md#签名验签规格)”一节。 +使用对称密钥初始化Mac计算。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------- | ------ | ---- | ------------------------------------------------------------ | -| algName | string | 是 | 指定签名算法:RSA或ECC,使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------- | +| key | [SymKey](#symkey) | 是 | 共享对称密钥。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | -**返回值**: +**错误码:** -| 类型 | 说明 | -| ------ | ---------------------------------- | -| Verify | 返回由输入算法指定生成的Verify对象 | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17630001 | crypto operation error. | **示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -let verifyer1 = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256"); - -let verifyer2 = cryptoFramework.createVerify("RSA1024|PSS|SHA256|MGF1_SHA256") +var mac; +try { + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +} +var KeyBlob; +var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); +symKeyGenerator.convertKey(KeyBlob, (err, symKey) => { + if (err) { + console.error("[Callback] err: " + err.code); + } + mac.init(symKey, (err1, ) => { + if (err1) { + console.error("[Callback] err: " + err1.code); + } + }); +}); ``` -## Verify +### init -Verify类,使用Verify方法之前需要创建该类的实例进行操作,通过createVerify(algName : string) : Verify方法构造此实例。 +init(key: SymKey): Promise\ -Verify类不支持重复初始化,当业务方需要使用新密钥验签时,需要重新创建新Verify对象并调用init初始化。 +使用对称密钥初始化Mac计算。 -业务方使用时,在createVerify时确定验签的模式,调用init接口设置密钥。 +**系统能力:** SystemCapability.Security.CryptoFramework -当签名数据较短时,可在init初始化后直接调用verify接口传入签名数据和原文进行验签。 +**参数:** -当签名数据较长时,可通过update接口分段传入签名数据,最后调用verify接口对整体签名数据进行验签。 +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ------------ | +| key | [SymKey](#symkey) | 是 | 共享对称密钥。 | -当使用update分段传入签名数据时,verify接口的签名数据支持传null,业务方可在循环中调用update接口,循环结束后调用verify传入原文进行验签。 +**返回值:** -### 属性 +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | -**系统能力:** SystemCapability.Security.CryptoFramework +**错误码:** -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ---------------------------- | -| algName | string | 是 | 否 | 验签指定的算法名称。 | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17630001 | crypto operation error. | +**示例:** +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -### init +var mac; +try { + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Mac algName is: " + mac.algName); + +var KeyBlob; +var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); +var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); +promiseConvertKey.then(symKey => { + var promiseMacInit = mac.init(symKey); + return promiseMacInit; +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); -init(pubKey : PubKey, callback : AsyncCallback\) : void +``` -传入公钥初始化Verify对象,Callback形式 +### update + +update(input: DataBlob, callback: AsyncCallback\): void + +传入消息进行Mac更新计算。 + +> **说明:** +> Hmac算法多次调用update更新的代码示例详见开发指导“[使用消息认证码操作](../../security/cryptoFramework-guidelines.md#使用消息认证码操作)”。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------------------------- | -| pubKey | [PubKey](#pubkey) | 是 | 公钥对象,用于Verify的初始化 | -| callback | AsyncCallback\ | 是 | 回调函数 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------- | ---- | ------------ | +| input | [DataBlob](#datablob) | 是 | 传入的消息。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 401 | invalid parameters. | | 17630001 | crypto operation error. | -### init +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +var KeyBlob; +var mac; +try { + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); +symKeyGenerator.convertKey(KeyBlob, (err, symKey) => { + if (err) { + console.error("[Callback] err: " + err.code); + } + mac.init(symKey, (err1, ) => { + if (err1) { + console.error("[Callback] err: " + err1.code); + } + let blob; + mac.update(blob, (err2, data) => { + if (err2) { + console.error("[Callback] err: " + err2.code); + } + }); + }); +}); +``` + +### update -init(pubKey : PubKey) : Promise\ +update(input: DataBlob): Promise\ -传入公钥初始化Verify对象,Promise形式 +传入消息进行Mac更新计算。 + +> **说明:** +> Hmac算法多次调用update更新的代码示例详见开发指导“[使用消息认证码操作](../../security/cryptoFramework-guidelines.md#使用消息认证码操作)”。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ---- | ---- | ---------------------------- | -| pubKey | [PubKey](#pubkey) | 是 | 公钥对象,用于Verify的初始化 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ---------- | +| input | [DataBlob](#datablob) | 是 | 传入的消息。 | **返回值:** -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +| 类型 | 说明 | +| -------------- | ------------- | +| Promise\ | Promise对象。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 401 | invalid parameters. | | 17630001 | crypto operation error. | -### update +**示例:** -update(data : DataBlob, callback : AsyncCallback\) : void +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -追加待验签数据,callback方式 +var mac; +try { + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Mac algName is: " + mac.algName); -> **说明:** -> Verify多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 +var KeyBlob; +var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); +var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); +promiseConvertKey.then(symKey => { + var promiseMacInit = mac.init(symKey); + return promiseMacInit; +}).then(() => { + let blob; + var promiseMacUpdate = mac.update(blob); + return promiseMacUpdate; +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); + +``` + +### doFinal + +doFinal(callback: AsyncCallback\): void + +返回Mac的计算结果。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------- | -| data | [DataBlob](#datablob)| 是 | 传入的消息 | -| callback | AsyncCallback\ | 是 | 回调函数 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------ | ---- | -------- | +| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | -### update +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +var KeyBlob; +var mac; +try { + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); +symKeyGenerator.convertKey(KeyBlob, (err, symKey) => { + if (err) { + console.error("[Callback] err: " + err.code); + } + mac.init(symKey, (err1, ) => { + if (err1) { + console.error("[Callback] err: " + err1.code); + } + let blob; + mac.update(blob, (err2, ) => { + if (err2) { + console.error("[Callback] err: " + err2.code); + } + mac.doFinal((err3, macOutput) => { + if (err3) { + console.error("[Callback] err: " + err3.code); + } else { + console.error("[Promise]: HMAC result: " + macOutput); + } + }); + }); + }); +}); +``` + +### doFinal + +doFinal(): Promise\ + +返回Mac的计算结果。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +**返回值:** + +| 类型 | 说明 | +| ------------------ | ----------- | +| Promise\<[DataBlob](#datablob)> | Promise对象。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | + +**示例:** -update(data : DataBlob) : Promise\; +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +var mac; +try { + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Mac algName is: " + mac.algName); + +var KeyBlob; +var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); +var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); +promiseConvertKey.then(symKey => { + var promiseMacInit = mac.init(symKey); + return promiseMacInit; +}).then(() => { + let blob; + var promiseMacUpdate = mac.update(blob); + return promiseMacUpdate; +}).then(() => { + var PromiseMacDoFinal = mac.doFinal(); + return PromiseMacDoFinal; +}).then(macOutput => { + console.error("[Promise]: HMAC result: " + macOutput.data); +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); +``` + +### getMacLength -追加待验签数据,promise方式 +getMacLength(): number -> **说明:** -> Verify多次调用update的代码示例详见开发指导“[使用签名验签操作](../../security/cryptoFramework-guidelines.md#使用签名验签操作)”。 +获取Mac消息认证码的长度(字节数)。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** - -| 参数名 | 类型 | 必填 | 说明 | -| ------ | -------- | ---- | ---------- | -| data | [DataBlob](#datablob) | 是 | 传入的消息 | - **返回值:** -| 类型 | 说明 | -| -------------- | ----------- | -| Promise\ | Promise对象 | +| 类型 | 说明 | +| ------ | --------------------------- | +| number | 返回mac计算结果的字节长度。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | | 17630001 | crypto operation error. | -### verify - -verify(data : DataBlob, signatureData : DataBlob, callback : AsyncCallback\) : void - -对数据进行验签,返回验签结果,callback方式 - -**系统能力:** SystemCapability.Security.CryptoFramework - -**参数:** +**示例:** -| 参数名 | 类型 | 必填 | 说明 | -| ------------- | -------------------- | ---- | ---------- | -| data | [DataBlob](#datablob) | 是 | 传入的消息 | -| signatureData | [DataBlob](#datablob) | 是 | 签名数据 | -| callback | AsyncCallback\ | 是 | 回调函数 | +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" -**错误码:** +var mac; +try { + mac = cryptoFramework.createMac("SHA256"); +} catch (error) { + console.error("[Promise]: error code: " + error.code + ", message is: " + error.message); +} +console.error("Mac algName is: " + mac.algName); -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error. | +var KeyBlob; +var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128"); +var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob); +promiseConvertKey.then(symKey => { + var promiseMacInit = mac.init(symKey); + return promiseMacInit; +}).then(() => { + let blob; + var promiseMacUpdate = mac.update(blob); + return promiseMacUpdate; +}).then(() => { + var PromiseMacDoFinal = mac.doFinal(); + return PromiseMacDoFinal; +}).then(macOutput => { + console.error("[Promise]: HMAC result: " + macOutput.data); + let macLen = mac.getMacLength(); + console.error("MAC len: " + macLen); +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); +``` -### verify +## cryptoFramework.createRandom -verify(data : DataBlob, signatureData : DataBlob) : Promise\ +createRandom(): Random -对数据进行验签,返回验签结果,promise方式 +生成Random实例,用于进行随机数的计算与设置种子。
支持的规格详见框架概述“[随机数算法规格](../../security/cryptoFramework-overview.md#随机数)”一节。 **系统能力:** SystemCapability.Security.CryptoFramework -**参数:** - -| 参数名 | 类型 | 必填 | 说明 | -| ------------- | -------- | ---- | ---------- | -| data | [DataBlob](#datablob) | 是 | 传入的消息 | -| signatureData | [DataBlob](#datablob) | 是 | 签名数据 | - -**返回值:** +**返回值**: -| 类型 | 说明 | -| ----------------- | ---------------------------- | -| Promise\ | 异步返回值,代表验签是否通过 | +| 类型 | 说明 | +| ------ | ----------------------------------------------- | +| Random | 返回由输入算法指定生成的[Random](#random)对象。 | **错误码:** -| 错误码ID | 错误信息 | -| -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | -| 17630001 | crypto operation error. | +| 错误码ID | 错误信息 | +| -------- | ------------ | +| 17620001 | memory error. | -**callback示例:** +**示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 -let input1 = null; -let input2 = null; -let signMessageBlob = null; // 签名后的数据,此处省略 -let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA25"); -verifyer.init(globalKeyPair.pubKey, function (err, data) { - verifyer.update(input1, function(err, data) { - verifyer.verify(input2, signMessageBlob, function(err, data) { - console.info("verify result is " + data); - }) - }); -}) +try { + var rand = cryptoFramework.createRandom(); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} ``` -**promise示例:** +## Random -```javascript -import cryptoFramework from "@ohos.security.cryptoFramework" +Random类,调用Random方法可以进行随机数计算。调用前,需要通过[createRandom](#cryptoframeworkcreaterandom)构造Random实例。 -let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 -let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256"); -let verifyInitPromise = verifyer.init(globalKeyPair.pubKey); -let input1 = null; -let input2 = null; -let signMessageBlob = null; // 签名后的数据,此处省略 -verifyInitPromise.then(() => { - return verifyer.update(input1); -}).then(() => { - return verifyer.verify(input2, signMessageBlob); -}).then(res => { - console.log("Verify result is " + res); -}); -``` +### 属性 -## cryptoFramework.createKeyAgreement +**系统能力:** SystemCapability.Security.CryptoFramework + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------- | ------ | ---- | ---- | -------------------- | +| algName10+ | string | 是 | 否 | 代表当前使用的随机数生成算法,目前只支持“CTR_DRBG"。 | -createKeyAgreement(algName : string) : KeyAgreement +### generateRandom -KeyAgreement实例生成。
支持的规格详见框架概述“[密钥协商规格](../../security/cryptoFramework-overview.md#密钥协商规格)”一节。 +generateRandom(len: number, callback: AsyncCallback\): void + +异步生成指定长度的随机数。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------- | ------ | ---- | ------------------------------- | -| algName | string | 是 | 指定密钥协商算法:目前仅支持ECC | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------ | ---- | -------------------- | +| len | number | 是 | 表示生成随机数的长度,单位为byte,范围在[1, INT_MAX]。 | +| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 回调函数。 | -**返回值**: +**错误码:** -| 类型 | 说明 | -| ------------ | ---------------------------------------- | -| KeyAgreement | 返回由输入算法指定生成的KeyAgreement对象 | +| 错误码ID | 错误信息 | +| -------- | ---------------------- | +| 401 | invalid parameters. | +| 17620001 | memory error. | +| 17630001 | crypto operation error. | **示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -let keyAgreement = cryptoFramework.createKeyAgreement("ECC256"); - +var rand; +try { + rand = cryptoFramework.createRandom(); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} +rand.generateRandom(12, (err, randData) => { + if (err) { + console.error("[Callback] err: " + err.code); + } else { + console.error("[Callback]: generate random result: " + randData.data); + } +}); ``` -## KeyAgreement +### generateRandom -KeyAgreement类,使用密钥协商方法之前需要创建该类的实例进行操作,通过createKeyAgreement(algName : string) : KeyAgreement方法构造此实例。 +generateRandom(len: number): Promise\ -### 属性 +异步生成指定长度的随机数。 **系统能力:** SystemCapability.Security.CryptoFramework -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ------- | ------ | ---- | ---- | ---------------------------- | -| algName | string | 是 | 否 | 密钥协商指定的算法名称。 | - -### generateSecret - -generateSecret(priKey : PriKey, pubKey : PubKey, callback : AsyncCallback\) : void - -基于传入的私钥与公钥进行密钥协商,返回共享秘密,Callback形式 +**参数:** -**系统能力:** SystemCapability.Security.CryptoFramework +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ------------------------------------------------------ | +| len | number | 是 | 表示生成随机数的长度,单位为byte,范围在[1, INT_MAX]。 | -**参数:** +**返回值:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------ | ---- | ---------------------- | -| priKey | [PriKey](#prikey) | 是 | 设置密钥协商的私钥输入 | -| pubKey | [PubKey](#pubkey) | 是 | 设置密钥协商的公钥输入 | -| callback | AsyncCallback\<[DataBlob](#datablob)> | 是 | 异步接受共享秘密的回调 | +| 类型 | 说明 | +| ------------------ | ----------- | +| Promise\<[DataBlob](#datablob)> | Promise对象。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 401 | invalid parameters. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | -### generateSecret +**示例:** + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +var rand; +try { + rand = cryptoFramework.createRandom(); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} + +var promiseGenerateRand = rand.generateRandom(12); +promiseGenerateRand.then(randData => { + console.error("[Promise]: rand result: " + randData.data); +}).catch(error => { + console.error("[Promise]: error: " + error.message); +}); +``` + +### generateRandomSync10+ -generateSecret(priKey : PriKey, pubKey : PubKey) : Promise\ +generateRandomSync(len: number): DataBlob -基于传入的私钥与公钥进行密钥协商,返回共享秘密,Promise形式 +以同步方法生成指定长度的随机数。 **系统能力:** SystemCapability.Security.CryptoFramework **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ------ | ---- | ---------------------- | -| priKey | [PriKey](#prikey) | 是 | 设置密钥协商的私钥输入 | -| pubKey | [PubKey](#pubkey) | 是 | 设置密钥协商的公钥输入 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | -------------------- | +| len | number | 是 | 表示生成随机数的长度,单位为byte,范围在[1, INT_MAX]。 | **返回值:** -| 类型 | 说明 | -| ------------------ | -------- | -| Promise\<[DataBlob](#datablob)> | 共享秘密 | +| 类型 | 说明 | +| ------------------ | ----------- | +|[DataBlob](#datablob) | 表示生成的随机数。 | **错误码:** | 错误码ID | 错误信息 | | -------- | ---------------------- | -| 17620001 | memory error. | -| 17620002 | runtime error. | +| 401 | invalid parameters. | +| 17620001 | memory error. | | 17630001 | crypto operation error. | -**callback示例:** +**示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 -let keyAgreement = cryptoFramework.createKeyAgreement("ECC256"); -keyAgreement.generateSecret(globalKeyPair.priKey, globalKeyPair.pubKey, function (err, secret) { - if (err) { - console.error("keyAgreement error."); - return; - } - console.info("keyAgreement output is " + secret.data); +var rand; +try { + rand = cryptoFramework.createRandom(); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} + +var generateRand = rand.generateRandomSync(12); +generateRand.then(randData => { + console.error("[Sync]: rand result: " + randData.data); +}).catch(error => { + console.error("[Sync]: error: " + error.message); }); ``` -**promise示例:** +### setSeed + +setSeed(seed: DataBlob): void + +设置指定的种子。 + +**系统能力:** SystemCapability.Security.CryptoFramework + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------- | ---- | ------------ | +| seed | DataBlob | 是 | 设置的种子。 | + +**错误码:** + +| 错误码ID | 错误信息 | +| -------- | ----------------- | +| 17620001 | memory error. | + +**示例:** ```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -let globalKeyPair; // globalKeyPair为使用非对称密钥生成器生成的非对称密钥对象,此处省略生成过程 -let keyAgreement = cryptoFramework.createKeyAgreement("ECC256"); -let keyAgreementPromise = keyAgreement.generateSecret(globalKeyPair.priKey, globalKeyPair.pubKey); -keyAgreementPromise.then((secret) => { - console.info("keyAgreement output is " + secret.data); -}).catch((error) => { - console.error("keyAgreement error."); +var rand; +try { + rand = cryptoFramework.createRandom(); +} catch (error) { + console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); +} + +rand.generateRandom(12, (err, randData) => { + if (err) { + console.error("[Callback] err: " + err.code); + } else { + console.error("[Callback]: generate random result: " + randData.data); + try { + rand.setSeed(randData); + } catch (error) { + console.log("setSeed failed, errCode: " + error.code + ", errMsg: " + error.message); + } + } }); -``` +``` \ No newline at end of file diff --git a/zh-cn/application-dev/security/cryptoFramework-guidelines.md b/zh-cn/application-dev/security/cryptoFramework-guidelines.md index 8c6a5429a8..8522b2a10e 100644 --- a/zh-cn/application-dev/security/cryptoFramework-guidelines.md +++ b/zh-cn/application-dev/security/cryptoFramework-guidelines.md @@ -4,21 +4,21 @@ > > 本开发指导基于API version 9,OH SDK版本3.2.7以上,适用于JS语言开发 -## 使用密钥对象生成与转换操作 +## 密钥对象生成与转换操作 -**场景说明** +### 场景说明 使用密钥生成操作中,典型的场景有: 1. 随机生成算法库密钥对象。该对象可用于后续的加解密等操作。 -2. 根据指定数据生成算法库密钥对象(也就是将外部或存储的二进制数据转换为算法库的密钥对象)。该对象可用于后续的加解密等操作。 -3. 获取算法库密钥对象的二进制数据,用于存储或传输。 +2. 根据密钥参数生成指定的算法库密钥对象。该对象可用于后续的加解密等操作。 +3. 根据指定数据生成算法库密钥对象(也就是将外部或存储的二进制数据转换为算法库的密钥对象)。该对象可用于后续的加解密等操作。 +4. 获取算法库密钥对象的二进制数据,用于存储或传输。 +5. 对于非对称密钥,获取密钥对象的参数属性,用于存储或运输。 +> **说明**:密钥对象Key包括对称密钥SymKey和非对称密钥(公钥PubKey和私钥PriKey),其中公钥和私钥组成密钥对KeyPair。密钥之间的具体关系可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 -> **说明:** -> -> 密钥对象Key包括对称密钥SymKey和非对称密钥(公钥PubKey和私钥PriKey),其中公钥和私钥组成密钥对KeyPair。密钥之间的具体关系可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 -**接口及参数说明** +### 接口及参数说明 详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 @@ -27,6 +27,7 @@ |实例名|接口名|描述| |---|---|---| |cryptoFramework|createAsyKeyGenerator(algName : string) : AsyKeyGenerator|根据algName设置的非对称密钥规格,创建非对称密钥生成器对象| +|cryptoFramework|createAsyKeyGeneratorBySpec(asyKeySpec: AsyKeySpec): AsyKeyGeneratorBySpec;|根据密钥参数设置的非对称密钥规格,创建非对称密钥生成器对象| |cryptoFramework|createSymKeyGenerator(algName : string) : SymKeyGenerator|根据algName设置的对称密钥规格,创建对称密钥生成器对象| |AsyKeyGenerator|generateKeyPair(callback : AsyncCallback\) : void|使用callback方式,随机生成非对称密钥对象KeyPair| |AsyKeyGenerator|generateKeyPair() : Promise\|使用Promise方式,随机生成非对称密钥对象KeyPair| @@ -38,8 +39,7 @@ | SymKeyGenerator |convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\| 使用Promise方式,根据指定的二进制数据,生成对称密钥对象SymKey | | Key | getEncoded() : DataBlob; | 获取Key密钥对象的二进制数据(Key的子类实例包括对称密钥SymKey、公钥PubKey、私钥PriKey) | -**开发步骤** - +### 随机生成RSA密钥对,并获得二进制数据 示例1:随机生成非对称密钥KeyPair,并获得二进制数据(场景1、3) 1. 创建非对称密钥生成器; @@ -48,7 +48,7 @@ 以使用Promise方式随机生成RSA密钥(1024位,素数个数为2)为例: -```js +```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; function generateAsyKey() { @@ -69,6 +69,7 @@ function generateAsyKey() { } ``` +### 随机生成AES密钥,并获得二进制数据 示例2:随机生成对称密钥SymKey,并获得二进制数据(场景1、3) 1. 创建对称密钥生成器; @@ -77,7 +78,7 @@ function generateAsyKey() { 以使用Promise方式随机生成AES密钥(256位)为例: -```js +```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; // 字节流以16进制输出 @@ -100,12 +101,14 @@ function testGenerateAesKey() { } ``` +### 根据RSA密钥二进制数据,生成密钥对 + 示例3:根据指定的RSA非对称密钥二进制数据,生成KeyPair对象(场景2) 1. 获取RSA公钥或私钥二进制数据,公钥需满足ASN.1语法、X.509规范、DER编码格式,私钥需满足ASN.1语法、PKCS#8规范、DER编码格式。 2. 创建AsyKeyGenerator对象,调用convertKey方法,传入公钥二进制和私钥二进制(二者非必选项,可只传入其中一个),转换为KeyPair对象。 -```js +```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; function convertAsyKey() { @@ -121,24 +124,24 @@ function convertAsyKey() { } ``` -> **说明:** -> -> 当前convertKey操作,公钥只支持转换满足X.509规范的DER格式,私钥只支持PKCS#8规范的DER格式。 +**说明** + + 当前convertKey操作,公钥只支持转换满足X.509规范的DER格式,私钥只支持PKCS#8规范的DER格式; + +### 根据ECC密钥二进制数据,生成密钥对 示例4:根据指定的ECC非对称密钥二进制数据,生成KeyPair对象(场景2、3) 1. 获取ECC二进制密钥数据,封装成DataBlob对象。 2. 调用convertKey方法,传入公钥二进制和私钥二进制(二者非必选项,可只传入其中一个),转换为KeyPair对象。 -```js -import cryptoFramework from "@ohos.security.cryptoFramework" - +```javascript function convertEccAsyKey() { let pubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]); let priKeyArray = new Uint8Array([48,49,2,1,1,4,32,115,56,137,35,207,0,60,191,90,61,136,105,210,16,27,4,171,57,10,61,123,40,189,28,34,207,236,22,45,223,10,189,160,10,6,8,42,134,72,206,61,3,1,7]); let pubKeyBlob = { data: pubKeyArray }; let priKeyBlob = { data: priKeyArray }; - let generator = cryptoFramework.createAsyKeyGenerator("ECC256"); + let generator = cryptoFrameWork.createAsyKeyGenerator("ECC256"); generator.convertKey(pubKeyBlob, priKeyBlob, (error, data) => { if (error) { AlertDialog.show({message : "Convert keypair fail"}); @@ -148,6 +151,7 @@ function convertEccAsyKey() { } ``` +### 根据3DES密钥二进制数据,生成密钥 示例5:根据指定的对称密钥二进制数据,生成SymKey对象(场景2、3) 1. 创建对称密钥生成器; @@ -156,7 +160,7 @@ function convertEccAsyKey() { 以使用callback方式生成3DES密钥(3DES密钥只能为192位)为例: -```js +```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; // 字节流以16进制输出 @@ -197,21 +201,222 @@ function testConvertAesKey() { } } ``` +## 非对称密钥对象根据参数生成与获取参数 + +### 场景说明 + +使用密钥生成操作中,典型的场景有: + +1. 根据非对称密钥参数生成指定的算法库密钥对象。该对象可用于后续的加解密等操作。 +2. 对于非对称密钥,获取密钥对象的参数属性,用于存储或运输。 +> **说明**:
+> 1. 从API version 10开始, 支持使用密钥参数来生成非对称密钥。 +> 2. 非对称密钥(公钥PubKey和私钥PriKey),其中公钥和私钥组成密钥对KeyPair。非对称密钥参数具体可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 + + +### 接口及参数说明 + +详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md#asykeygeneratorbyspec10)。 + +以上场景涉及的常用接口如下表所示: + +|实例名|接口名|描述| +|---|---|---| +|AsyKeyGeneratorBySpec|generateKeyPair(callback: AsyncCallback): void;|使用callback方式,根据密钥参数生成非对称密钥对象KeyPair +|AsyKeyGeneratorBySpec|generateKeyPair(): Promise;|使用Promise方式,根据密钥参数生成非对称密钥对象KeyPair +|AsyKeyGeneratorBySpec|generatePriKey(callback: AsyncCallback): void;|使用callback方式,根据密钥参数生成非对称私钥对象PriKey +|AsyKeyGeneratorBySpec|generatePriKey(): Promise;|使用Promise方式,根据密钥参数生成非对称私钥对象PriKey +|AsyKeyGeneratorBySpec|generatePubKey(callback: AsyncCallback): void;|使用callback方式,根据密钥参数生成非对称公钥对象PubKey +|AsyKeyGeneratorBySpec|generatePubKey(): Promise;|使用Promise方式,根据密钥参数生成非对称公钥对象PubKey +| PriKey | getAsyKeySpec(itemType: AsyKeySpecItem): bigint \| string \| number; | 获取非对称密钥私钥对象的密钥参数属性 | +| PubKey | getAsyKeySpec(itemType: AsyKeySpecItem): bigint \| string \| number; | 获取非对称密钥公钥对象的密钥参数属性 | + +### 根据参数生成ECC密钥对,并获得密钥参数开发步骤 +示例1:根据参数生成ECC密钥对,并获得密钥参数(场景1、2) + +1. 创建根据密钥参数的非对称密钥生成器; +2. 通过根据密钥参数的非对称密钥生成器由指定密钥参数生成非对称密钥对; +3. 获取密钥对象的密钥参数属性; + +以使用Promise方式根据密钥参数生成ECC密钥为例: +```javascript +import cryptoFramework from '@ohos.security.cryptoFramework'; + +// 打印bigint信息 +function showBigIntInfo(bnName, bnValue) { + console.warn(bnName + ":"); + console.warn(". 十进制: " + bnValue.toString()); + console.warn(". 16进制: " + bnValue.toString(16)); + console.warn(". 长度(bits): " + bnValue.toString(2).length); +} + +// 根据密钥参数属性,构造ECC公私钥共有参数的sepc结构体 +function genEccCommonSpec() { + let fieldFp = { + fieldType : "Fp", + p : BigInt("0xffffffffffffffffffffffffffffffff000000000000000000000001") + } + + let G = { + x : BigInt("0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21"), + y : BigInt("0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34") + } + + let eccCommonSpec = { + algName : "ECC", + specType : cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + field : fieldFp, + a : BigInt("0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe"), + b : BigInt("0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4"), + g : G, + n : BigInt("0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d"), + h : 1 + } + return eccCommonSpec; +} + +// 打印ECC密钥参数属性 +function showEccSpecDetailInfo(key, keyType) { + console.info("show detail of " + keyType + ":"); + try { + let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN); + showBigIntInfo("--- p", p); //length is 224, hex : ffffffffffffffffffffffffffffffff000000000000000000000001 + + let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); + showBigIntInfo("--- a", a); // length is 224, hex : fffffffffffffffffffffffffffffffefffffffffffffffffffffffe + + let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); + showBigIntInfo("--- b", b); // length is 224, hex : b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 + + let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); + showBigIntInfo("--- gX", gX); // length is 224, hex : b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 + + let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); + showBigIntInfo("--- gY", gY); // length is 224, hex : bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 + + let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); + showBigIntInfo("--- n", n); // length is 224, hex : ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d + + let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); + console.warn("--- h: " + h); //key h: 1 + + let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); + console.warn("--- field type: " + fieldType); // key field type: Fp + + let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); + console.warn("--- field size: " + fieldSize); // key field size: 224 + + let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); + console.warn("--- curve name: " + curveName); // key curve name: NID_secp224r1 + + if (keyType == "priKey") { + let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN); + showBigIntInfo("--- sk", sk); + } else if (keyType == "pubKey") { + let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN); + showBigIntInfo("--- pkX", pkX); + let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN); + showBigIntInfo("--- pkY", pkY); + } + } catch (error) { + console.error("getAsyKeySpec error"); + console.error("error code: " + error.code + ", message is: " + error.message); + } +} + +// 测试根据ECC公私钥公共密钥参数生成ECC密钥对,并获得其密钥参数属性 +function testEccUseCommKeySpecGet() +{ + try { + let commKeySpec = genEccCommonSpec(); // 使用参数属性,构造ECC公私钥公共密钥参数对象 + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(commKeySpec); // 使用密钥参数对象创建生成器 + let keyPairPromise = generatorBySpec.generateKeyPair(); // 使用生成器创建ECC密钥对 + keyPairPromise.then( keyPair => { + showEccSpecDetailInfo(keyPair.priKey, "priKey"); // 对私钥获取相关密钥参数属性 + showEccSpecDetailInfo(keyPair.pubKey, "pubKey"); // 对公钥获取相关密钥参数属性 + }).catch(error => { + console.error("generateComm error"); + console.error("error code: " + error.code + ", message is: " + error.message); + }) + } catch(error) { + console.error("testEccUseCommSpec error"); + console.error("error code: " + error.code + ", message is: " + error.message); + } +} +``` + +### 根据参数生成RSA公钥,并获得密钥参数属性 +示例2:根据参数生成RSA公钥,并获得密钥参数(场景1、2) + +1. 创建根据密钥参数的非对称密钥生成器; +2. 通过根据密钥参数的非对称密钥生成器由指定密钥参数生成非对称密钥的公钥; +3. 获取密钥对象的密钥参数属性; + +以使用Callback方式根据密钥参数生成RSA公钥为例: +``` javascript +import cryptoFramework from '@ohos.security.cryptoFramework'; + +// RSA公钥密钥参数生成函数 +function genRsaPubKeySpec(nIn : bigint, eIn : bigint) { + let rsaCommSpec = { n : nIn, algName : "RSA", specType : cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC }; + let rsaPubKeySpec = { params: rsaCommSpec, pk : eIn, algName : "RSA", specType : cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC }; + return rsaPubKeySpec; +} + +// 根据密钥参数属性,构造RSA公钥密钥参数对象 +function genRsa2048PubKeySpec() { + let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25"); + let eIn = BigInt("0x010001"); + return genRsaPubKeySpec(nIn, eIn); +} + +// 将RSA公钥密钥参数属性与预期值比较 +function compareRsaPubKeyBySpec(rsaKeySpec, n, e) { + if (rsaKeySpec.params.n != n) { + return false; + } + if (rsaKeySpec.pk != e) { + return false; + } + return true; +} + +// 测试根据RSA公钥密钥参数生成RSA公钥,并获得其密钥参数属性,与预期值做比较 +function rsaUsePubKeySpecGetCallback() { + let rsaPubKeySpec = genRsa2048PubKeySpec(); + let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaPubKeySpec); + rsaGeneratorSpec.generatePubKey((error, key) => { + let pubKey = key; + let nBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_N_BN); + let eBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PK_BN); + if (compareRsaPubKeyBySpec(rsaPubKeySpec, nBN, eBN) != true) { + AlertDialog.show({ message : "error pub key big number"} ); + } else { + console.info("n, e in the pubKey are same as the spec."); + } + if (error) { + console.error("generate pubKey error" + "error code: " + error.code + "error message" + error.message); + } + }); +} +``` ## 使用加解密操作 -**场景说明** +### 场景说明 在数据存储或传输场景中,可以使用加解密操作用于保证数据的机密性,防止敏感数据泄露。使用加解密操作中,典型的场景有: - 1. 使用对称密钥的加解密操作 2. 使用非对称密钥的加解密操作 +3. 使用RSA, PKCS1_OAEP填充模式时,获取、设置CipherSpecItem参数 -**接口及参数说明** +> **说明**:
+> 1. 从API version 10开始, 支持RSA使用PKCS1_OAEP填充模式时,获取、设置[CipherSpecItem](../reference/apis/js-apis-cryptoFramework.md#cipherspecitem10)参数。 +> 2. 从API version 10开始,支持加解密时字符串参数不带密钥长度。 -详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 +### 接口及参数说明 -由于密码算法的复杂性,在选取不同规格和参数时,开发差异较大,无法通过代码示例一一列举,请仔细阅读API参考资料中的相关接口,确保使用正确。 +详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
由于密码算法的复杂性,在选取不同规格和参数时,开发差异较大,无法通过代码示例一一列举,请仔细阅读API参考资料中的相关接口,确保使用正确。 以上场景设计的常用接口如下表所示: @@ -224,19 +429,19 @@ function testConvertAesKey() { |Cipher|update(data : DataBlob) : Promise\|使用Promise方式添加加解密数据| |Cipher|doFinal(data : DataBlob, callback : AsyncCallback\) : void|使用callback方式结束对所有数据的加解密| |Cipher|doFinal(data : DataBlob) : Promise\|使用Promise方式结束对所有数据的加解密| +|Cipher|getCipherSpec(itemType: CipherSpecItem): string \| Uint8Array|获取加解密的参数,当前仅支持RSA算法| +|Cipher|setCipherSpec(itemType: CipherSpecItem, itemValue: Uint8Array): void|设置加解密的参数,当前仅支持RSA算法| -**开发步骤** +### AES GCM以Promise方式加解密开发步骤: -示例1:使用对称密钥的加解密操作 +示例1:使用AES对称密钥的加解密操作 1. 创建对称密钥生成器。 -2. 通过密钥生成器生成对称密钥。 +2. 通过密钥生成器随机生成对称密钥。 3. 创建加解密生成器。 4. 通过加解密生成器加密或解密数据。 -以AES GCM以Promise方式加解密为例: - -```js +``` javascript import cryptoFramework from '@ohos.security.cryptoFramework'; var globalCipher; @@ -256,7 +461,7 @@ function genGcmParamsSpec() { arr = [0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0]; // 16 bytes let dataTag = new Uint8Array(arr); let tagBlob = {data : dataTag}; // GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中 - + let gcmParamsSpec = {iv : ivBlob, aad : aadBlob, authTag : tagBlob, algName : "GcmParamsSpec"}; return gcmParamsSpec; } @@ -286,16 +491,6 @@ function uint8ArrayToString(array) { return arrayString; } -function genKeyMaterialBlob() { - let arr = [ - 0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56, - 0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c, - 0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72]; // keyLen = 192 (24 bytes) - let keyMaterial = new Uint8Array(arr); - return {data : keyMaterial}; -} - - // AES GCM模式示例,自动生成密钥(promise写法) function testAesGcm() { return new Promise((resolve, reject) => { @@ -370,7 +565,14 @@ function testAesGcm() { } ``` -以3DES ECB以callback方式加解密(采用已有数据生成密钥)为例: +### 3DES ECB以callback方式加解密开发步骤: + +示例2:使用3DES对称密钥的加解密操作 + +1. 创建对称密钥生成器。 +2. 通过已有二进制数据生成密钥 +3. 创建加解密生成器。 +4. 通过加解密生成器加密或解密数据。 ```js import cryptoFramework from '@ohos.security.cryptoFramework'; @@ -496,9 +698,18 @@ function test3DesEcb() { } ``` +### AES GCM以promise方式,分段update()加解密开发步骤: + +示例3:使用AES对称密钥的分段update()加解密操作 + +1. 创建对称密钥生成器。 +2. 通过已有二进制数据生成密钥 +3. 创建加解密生成器。 +4. 通过加解密生成器加密或解密数据。 + 以AES GCM以promise方式,分段update()实现加解密为例: -```js +```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; var globalCipher; @@ -584,7 +795,7 @@ function testAesMultiUpdate() { let messageArr = []; let updateLength = 20; // 假设每20字节分段update一次 globalCipherText = []; - + for (let i = 0; i <= plainText.length; i++) { if ((i % updateLength == 0 || i == plainText.length) && messageArr.length != 0) { let message = new Uint8Array(messageArr); @@ -637,77 +848,102 @@ function testAesMultiUpdate() { }) } ``` - -示例2:使用非对称密钥的加解密操作 +### RSA加解密开发步骤 +示例4:使用RSA非对称密钥的加解密操作 1. 生成RSA密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成RSA非对称密钥。 2. 生成Cipher对象。通过createCipher接口创建Cipher对象,执行初始化操作,设置密钥及加解密模式。 3. 执行加解密操作。通过调用Cipher对象提供的doFinal接口,执行加密操作生成密文或执行解密操作生成明文。 -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" let plan = "This is cipher test."; +// 可理解的字符串转成字节流 function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } - var tmpArray = new Uint8Array(arr); - return tmpArray; + return new Uint8Array(arr); } +// 以Promise方式加密 function encryptMessageProMise() { + // 生成非对称密钥生成器 let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); + // 生成加解密生成器 let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); + // 通过非对称秘钥生成器生成非对称密钥对 let keyGenPromise = rsaGenerator.generateKeyPair(); keyGenPromise.then(rsaKeyPair => { let pubKey = rsaKeyPair.pubKey; + // 初始化加解密操作环境:使用公钥开始加密 return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null); }).then(() => { + // doFinal let input = { data : stringToUint8Array(plan) }; return cipher.doFinal(input); }).then(dataBlob => { + // 获取加密后的信息 console.info("EncryptOutPut is " + dataBlob.data); }); } +// 以Callback方式加密 function encryptMessageCallback() { + // 生成非对称密钥生成器 let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); + // 生成加解密生成器 let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); + // 通过非对称秘钥生成器生成非对称密钥对 rsaGenerator.generateKeyPair(function (err, keyPair) { let pubKey = keyPair.pubKey; + // 初始化加解密操作环境:使用公钥开始加密 cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null, function (err, data) { let input = {data : stringToUint8Array(plan) }; + // doFinal cipher.doFinal(input, function (err, data) { + // 获取加密后的信息 console.info("EncryptOutPut is " + data.data); }) }) }) } +// 以Promise方式加解密 function decryptMessageProMise() { + // 生成非对称密钥生成器 let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); + // 生成加解密生成器,用于加密 let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); + // 生成加解密生成器,用于解密 let decoder = cryptoFramework.createCipher("RSA1024|PKCS1"); + // 通过非对称秘钥生成器生成非对称密钥对 let keyGenPromise = rsaGenerator.generateKeyPair(); let keyPair; let cipherDataBlob; let input = { data : stringToUint8Array(plan) }; keyGenPromise.then(rsaKeyPair => { keyPair = rsaKeyPair; + // 初始化加解密操作环境:使用公钥开始加密 return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null); }).then(() => { + // 加密doFinal return cipher.doFinal(input); }).then(dataBlob => { + // 获取加密后的信息,并用于解密的入参 console.info("EncryptOutPut is " + dataBlob.data); AlertDialog.show({message : "output" + dataBlob.data}); cipherDataBlob = dataBlob; + // 初始化加解密操作环境:使用私钥开始解密 return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null); }).then(() => { + // 解密doFinal return decoder.doFinal(cipherDataBlob); }).then(decodeData => { + // 验证解密后,数据与原先数据是否保持一致 if (decodeData.data.toString() === input.data.toString()) { AlertDialog.show({message : "decrypt success"}); return; @@ -716,22 +952,33 @@ function decryptMessageProMise() { }); } +// 以Callback方式加解密 function decryptMessageCallback() { + // 生成非对称密钥生成器 let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); + // 生成加解密生成器,用于加密 let cipher = cryptoFramework.createCipher("RSA1024|PKCS1"); + // 生成加解密生成器,用于解密 let decoder = cryptoFramework.createCipher("RSA1024|PKCS1"); let plainText = "this is cipher text"; let input = {data : stringToUint8Array(plainText) }; let cipherData; let keyPair; + // 通过非对称秘钥生成器生成非对称密钥对 rsaGenerator.generateKeyPair(function (err, newKeyPair) { keyPair = newKeyPair; + // 初始化加解密操作环境:使用公钥开始加密 cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null, function (err, data) { + // 加密doFinal cipher.doFinal(input, function (err, data) { + // 获取加密后的信息,并用于解密的入参 AlertDialog.show({ message : "EncryptOutPut is " + data.data} ); cipherData = data; + // 初始化加解密操作环境:使用私钥开始解密 decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null, function (err, data) { + // 解密doFinal decoder.doFinal(cipherData, function (err, data) { + // 验证解密后,数据与原先数据是否保持一致 if (input.data.toString() === data.data.toString()) { AlertDialog.show({ message : "decrype success"} ); return; @@ -744,19 +991,22 @@ function decryptMessageCallback() { }); } ``` +### RSA分段加解密开发步骤 +示例5:使用RSA非对称密钥的分段加解密操作 -以RSA非对称加解密(多次调用doFinal实现分段)为例: - -```js +1. 生成RSA密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成RSA非对称密钥。 +2. 生成Cipher对象。通过createCipher接口创建Cipher对象,执行初始化操作,设置密钥及加解密模式。 +3. 执行加解密操作。通过调用Cipher对象提供的doFinal接口,执行加密操作生成密文或执行解密操作生成明文,多次调用doFinal实现分段。 +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" +// 可理解的字符串转成字节流 function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } - var tmpArray = new Uint8Array(arr); - return tmpArray; + return new Uint8Array(arr); } // 字节流转成可理解的字符串 @@ -831,22 +1081,132 @@ function encryptLongMessagePromise() { } ``` -> **说明:** -> -> 1. 使用RSA加解密时,Cipher对象不可重复调用init方法初始化,在创建了一个加密Cipher对象后,如果要进行解密,则需要重新创建另一个Cipher对象执行解密操作。 -> 2. RSA加密有长度限制,允许加密明文的最大长度见[加解密算法库框架概述](cryptoFramework-overview.md)中的基本概念章节。 -> 3. RSA解密每次允许解密的密文长度为,RSA密钥的位数/8。 +**说明** + +1. 使用RSA加解密时,Cipher对象不可重复调用init方法初始化,在创建了一个加密Cipher对象后,如果要进行解密,则需要重新创建另一个Cipher对象执行解密操作。 +2. RSA加密有长度限制,允许加密明文的最大长度见[加解密算法库框架概述](cryptoFramework-overview.md)中的基本概念加解密章节。 +3. RSA解密每次允许解密的密文长度为,RSA密钥的位数/8。 + +### RSA加解密PKCS1_OAEP模式开发步骤 +示例6:使用RSA非对称密钥使用PKCS1_OAEP模式的以Promise形式的加解密操作 + +1. 根据密钥参数生成RSA密钥。通过createAsyKeyGeneratorBySpec接口创建AsyKeyGeneratorBySpec对象,并生成RSA非对称密钥对。(也可以使用createAsyKeyGenerator接口随机生成或转换得到RSA密钥对象) +2. 生成Cipher对象。通过createCipher接口创建Cipher对象,执行初始化操作,设置密钥及加解密模式,在Update前通过setCipherSpec设置PKCS1_OAEP填充字节流P。 +3. 执行加解密操作。通过调用Cipher对象提供的doFinal接口,执行加密操作生成密文或执行解密操作生成明文,需要加解密Cipher对象的字节流P一致。 +``` javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +// 可理解的字符串转成字节流 +function stringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); +} + +// 根据密钥参数属性构造RSA非对称密钥对密钥参数 +function genRsaKeyPairSpec(nIn : bigint, eIn : bigint, dIn : bigint) { + let rsaCommSpec = { n : nIn, algName : "RSA", specType : cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC }; + let rsaKeyPairSpec = { params: rsaCommSpec, sk : dIn, pk : eIn, algName : "RSA", specType : cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC }; + return rsaKeyPairSpec; +} + +// 生成RSA2048密钥对参数 +function genRsa2048KeyPairSpec() { + let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25"); + let eIn = BigInt("0x010001"); + let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1"); + return genRsaKeyPairSpec(nIn, eIn, dIn); +} + +function rsaUseSpecDecryptOAEPPromise() { + let plan = "This is cipher test."; + // 获得RSA密钥对密钥参数对象 + let rsaKeyPairSpec = genRsa2048KeyPairSpec(); + // 根据RSA密钥对参数生成RSA密钥对 + let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec); + let keyGenPromise = rsaGeneratorSpec.generateKeyPair(); + let cipher = cryptoFramework.createCipher("RSA|PKCS1_OAEP|SHA256|MGF1_SHA1"); + let decoder = cryptoFramework.createCipher("RSA|PKCS1_OAEP|SHA256|MGF1_SHA1"); + let keyPair; + let cipherDataBlob; + // RSA加解密PKCS1-OAEP模式填充字节流P + let pSource = new Uint8Array([1,2,3,4]); + let input = { data : stringToUint8Array(plan) }; + // 生成密钥 + keyGenPromise.then(rsaKeyPair => { + keyPair = rsaKeyPair; + // 进行加密操作初始化 + return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null); + }).then(() => { + // get和set操作可以放在Cipher对象init之后,此处对cipher进行set和get操作 + cipher.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource); + let retP = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR); + // 比较get出来的P字节流与set进去的P字节流是否一致 + if (retP.toString() != pSource.toString()) { + AlertDialog.show({message : "error init pSource" + retP}); + } else { + console.info("pSource changed ==" + retP); + } + // 进行OAEP其他参数的get操作 + let md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR); + console.info("md == " + md); + let mgf = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR); + console.info("mgf == " + mgf); + let mgf1Md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR); + console.info("mgf1Md == " + mgf1Md); + return cipher.doFinal(input); + }).then(dataBlob => { + console.info("EncryptOutPut is " + dataBlob.data); + cipherDataBlob = dataBlob; + // get和set操作可以放在Cipher对象init之前,且与init之后等价,此处对decoder进行set和get操作 + decoder.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource); + let retP = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR); + // 比较get出来的P字节流与set进去的P字节流是否一致 + if (retP.toString() != pSource.toString()) { + AlertDialog.show({message : "error init pSource" + retP}); + } else { + console.info("pSource changed ==" + retP); + } + // 进行OAEP其他参数的get操作 + let md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR); + console.info("md == " + md); + let mgf = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR); + console.info("mgf == " + mgf); + let mgf1Md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR); + console.info("mgf1Md == " + mgf1Md); + // 初始化解密操作 + return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null); + }).then(() => { + return decoder.doFinal(cipherDataBlob); + }).then(decodeData => { + // 解密成功 + if (decodeData.data.toString() === input.data.toString()) { + console.info("oaep decrypt success"); + AlertDialog.show({message : " oaep decrypt success"}); + } else { + AlertDialog.show({message : "oeap decrypt fail"}); + } + }); +} +``` + ## 使用签名验签操作 -**场景说明** +### 场景说明 当需要判断接收的数据是否被篡改且是否为指定对象发送的数据时,可以使用签名验签操作。使用签名验签操作中,典型的场景有: - 1. 使用RSA签名验签操作 2. 使用ECC签名验签操作 +3. 使用RSA签名验签,PSS模式时,获取、设置SignSpecItem参数。 + +> **说明**:
+> 1. 从API version 10开始,支持RSA使用PSS填充模式时,获取、设置[SignSpecItem](../reference/apis/js-apis-cryptoFramework.md#signspecitem10)参数。 +> 2. 从API version 10开始,支持签名验签时字符串参数不带密钥长度。 -**接口及参数说明** +### 接口及参数说明 详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
由于密码算法的复杂性,在选取不同规格和参数时,开发差异较大,无法通过代码示例一一列举,请仔细阅读API参考资料中的相关接口,确保使用正确。 @@ -859,34 +1219,36 @@ function encryptLongMessagePromise() { |Sign|update(data : DataBlob) : Promise\|用Promise方式添加签名数据| |Sign|sign(data : DataBlob, callback : AsyncCallback\) : void|使用callback方式签名所有数据| |Sign|sign(data : DataBlob) : Promise\|使用Promise方式签名所有数据| +|Sign|getSignSpec(itemType: SignSpecItem): string \| number|获得签名的参数,当前仅支持RSA算法| +|Sign|setSignSpec(itemType: SignSpecItem, itemValue: number): void|设置签名的参数,当前仅支持RSA算法| |cryptoFramework|function createVerify(algName : string) : Verify|根据String设置的参数创建Verify对象| -|Verify|init(priKey : PriKey, callback : AsyncCallback\) : void|使用callback方式设置密钥并初始化Verify对象| -|Verify|init(priKey : PriKey) : Promise\|使用Promise方式设置密钥并初始化Verify对象| +|Verify|init(pubKey : PubKey, callback : AsyncCallback\) : void|使用callback方式设置密钥并初始化Verify对象| +|Verify|init(pubKey : PubKey) : Promise\|使用Promise方式设置密钥并初始化Verify对象| |Verify|update(data : DataBlob, callback : AsyncCallback\) : void|使用callback方式添加验签数据| |Verify|update(data : DataBlob) : Promise\|用Promise方式添加验签数据| |Verify|verify(data : DataBlob, signatureData : DataBlob, callback : AsyncCallback\) : void|使用callback方式验签所有数据| |Verify|verify(data : DataBlob, signatureData : DataBlob) : Promise\|使用Promise方式验签所有数据| +|Verify|getVerifySpec(itemType: SignSpecItem): string \| number|获得验签的参数,当前仅支持RSA算法| +|Verify|setVerifySpec(itemType: SignSpecItem, itemValue: number): void|设置验签的参数,当前仅支持RSA算法| -**开发步骤** +### RSA签名验签开发步骤 示例1:使用RSA签名验签操作 - 1. 生成RSA密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成RSA非对称密钥。 2. 生成Sign对象。通过createSign接口创建Sign对象,执行初始化操作并设置签名私钥。 3. 执行签名操作。通过Sign类提供的update接口,添加签名数据,并调用sign接口生成数据的签名。 4. 生成Verify对象。通过createVerify接口创建Verify对象,执行初始化操作并设置验签公钥。 5. 执行验签操作。通过Verify类提供的update接口,添加签名数据,并调用verify接口传入签名进行验签。 - -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" +// 可理解的字符串转成字节流 function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); } - var tmpArray = new Uint8Array(arr); - return tmpArray; + return new Uint8Array(arr); } let globalKeyPair; @@ -898,7 +1260,7 @@ let input2 = { data : stringToUint8Array(plan2) }; function signMessagePromise() { let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); - let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); + let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); // API version 10开始,支持"RSA|PKCS1|SHA256" let keyGenPromise = rsaGenerator.generateKeyPair(); keyGenPromise.then( keyPair => { globalKeyPair = keyPair; @@ -928,7 +1290,7 @@ function verifyMessagePromise() { function signMessageCallback() { let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2"); - let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); + let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); // API version 10开始,支持"RSA|PKCS1|SHA256" rsaGenerator.generateKeyPair(function (err, keyPair) { globalKeyPair = keyPair; let priKey = globalKeyPair.priKey; @@ -955,24 +1317,25 @@ function verifyMessageCallback() { } ``` -示例2:使用ECDSA操作 +### ECDSA签名验签开发步骤 +示例2:使用ECDSA操作 1. 生成ECC密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成ECC非对称密钥。 2. 生成Sign对象。通过createSign接口创建Sign对象,执行初始化操作并设置签名私钥。 3. 执行签名操作。通过Sign类提供的update接口,添加签名数据,并调用doFinal接口生成数据的签名。 4. 生成Verify对象。通过createVerify接口创建Verify对象,执行初始化操作并设置验签公钥。 5. 执行验签操作。通过Verify类提供的update接口,添加签名数据,并调用doFinal接口传入签名进行验签。 -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" +// 可理解的字符串转成字节流 function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } - var tmpArray = new Uint8Array(arr); - return tmpArray; + return new Uint8Array(arr); } let globalKeyPair; @@ -1041,18 +1404,25 @@ function verifyMessageCallback() { } ``` -以执行签名、验签操作时多次调用update实现分段为例: +### RSA分段签名验签开发步骤 -```js +示例3:使用RSA签名验签操作 +1. 生成RSA密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成RSA非对称密钥。 +2. 生成Sign对象。通过createSign接口创建Sign对象,执行初始化操作并设置签名私钥。 +3. 执行签名操作。通过Sign类提供的update接口,多次添加签名数据,并调用sign接口生成数据的签名,完成分段签名。 +4. 生成Verify对象。通过createVerify接口创建Verify对象,执行初始化操作并设置验签公钥。 +5. 执行验签操作。多次通过Verify类提供的update接口,添加签名数据,并调用verify接口传入签名进行验签,完成分段验签。 + +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" +// 可理解的字符串转成字节流 function stringToUint8Array(str) { - var arr = []; - for (var i = 0, j = str.length; i < j; ++i) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } - var tmpArray = new Uint8Array(arr); - return tmpArray; + return new Uint8Array(arr); } function signLongMessagePromise() { @@ -1109,9 +1479,168 @@ function signLongMessagePromise() { } ``` +### RSA签名验签PSS模式开发步骤 + +示例4:使用RSA签名验签PSS模式,以Callback形式完成签名验签流程。 + +1. 根据密钥参数生成RSA密钥。通过createAsyKeyGeneratorBySpec接口创建AsyKeyGeneratorBySpec对象,并生成RSA非对称密钥对。 +2. 生成Sign对象。通过createSign接口创建Sign对象,执行初始化操作并设置签名私钥,可以获得、设置PSS模式相关参数。 +3. 执行签名操作。通过Sign类提供的update接口,添加签名数据,并调用sign接口生成数据的签名。 +4. 生成Verify对象。通过createVerify接口创建Verify对象,执行初始化操作并设置验签公钥,可以获得、设置PSS模式相关参数,验签成功需要保证盐值长度一致。 +5. 执行验签操作。通过Verify类提供的update接口,添加签名数据,并调用verify接口传入签名进行验签。 + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +// 可理解的字符串转成字节流 +function stringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); +} + +// 根据密钥参数属性构造RSA非对称密钥对密钥参数 +function genRsaKeyPairSpec(nIn : bigint, eIn : bigint, dIn : bigint) { + let rsaCommSpec = { n : nIn, algName : "RSA", specType : cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC }; + let rsaKeyPairSpec = { params: rsaCommSpec, sk : dIn, pk : eIn, algName : "RSA", specType : cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC }; + return rsaKeyPairSpec; +} + +// 生成RSA2048密钥对参数 +function genRsa2048KeyPairSpec() { + let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25"); + let eIn = BigInt("0x010001"); + let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1"); + return genRsaKeyPairSpec(nIn, eIn, dIn); +} + +function verifyMessageCallbackPSS() { + let plan1 = "This is Sign test plan1"; + let plan2 = "This is Sign test plan1"; + let input1 = { data : stringToUint8Array(plan1) }; + let input2 = { data : stringToUint8Array(plan2) }; + let globalKeyPair; + let signMessageBlob; + // 获得RSA密钥对密钥参数对象 + let rsaKeyPairSpec = genRsa2048KeyPairSpec(); + // 构造RSA密钥对生成器 + let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec); + // sign和verfiy均支持RSA密钥带长度/不带长度的写法 + let signer = cryptoFramework.createSign("RSA|PSS|SHA256|MGF1_SHA256"); + let verifyer = cryptoFramework.createVerify("RSA2048|PSS|SHA256|MGF1_SHA256"); + rsaGeneratorSpec.generateKeyPair(function (err, keyPair) { + globalKeyPair = keyPair; + signer.init(globalKeyPair.priKey, function (err, data) { + // 在签名初始化后,对PSS参数进行set和get操作 + let setN = 32; + signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN); + let saltLen = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); + console.info("SaltLen == " + saltLen); + let tf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM); + console.info("trailer field == " + tf); + let md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR); + console.info("md == " + md); + let mgf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR); + console.info("mgf == " + mgf); + let mgf1Md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR); + console.info("mgf1Md == " + mgf1Md); + signer.update(input1, function (err, data) { + signer.sign(input2, function (err, data) { + // 在验签初始化前,对PSS参数进行set和get操作,功能与初始化后一致 + signMessageBlob = data; + AlertDialog.show({message : "res" + signMessageBlob.data}); + let setN = 32; + verifyer.setVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN); + let saltLen = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); + console.info("SaltLen == " + saltLen); + let tf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM); + console.info("trailer field == " + tf); + let md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR); + console.info("md == " + md); + let mgf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR); + console.info("mgf == " + mgf); + let mgf1Md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR); + console.info("mgf1Md == " + mgf1Md); + verifyer.init(globalKeyPair.pubKey, function (err, data) { + verifyer.update(input1, function(err, data) { + verifyer.verify(input2, signMessageBlob, function(err, data) { + AlertDialog.show({message : "res " + data}); + }) + }); + }); + }); + }); + }); + }); +} +``` + +## 使用密钥协商操作 + +### 场景说明 + +使用密钥协商操作中,典型的场景有: + +通信双方可以在一个公开的信道上通过相互传送一些消息,共同建立一个安全的共享秘密密钥。 + +> **说明**:
+> 从API version 10开始,支持密钥协商时字符串参数不带密钥长度。 + +### 接口及参数说明 + +详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 + +|实例名|接口名|描述| +|---|---|---| +|cryptoFramework|createKeyAgreement(algName : string) : KeyAgreement|根据String设置的参数创建KeyAgreement对象| +|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey, callback : AsyncCallback\) : void|使用callback方式进行密钥协商| +|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey) : Promise\|使用Promise方式进行密钥协商| + +### 开发步骤 + +1. 生成ECC密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成ECC非对称密钥。 +2. 基于ECC密钥的私钥及公钥执行ECDH操作。 + +```javascript +import cryptoFramework from "@ohos.security.cryptoFramework" + +let globalKeyPair; + +function ecdhPromise() { + let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); + let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256"); // API version 10开始,支持输入"ECC"来进行密钥协商 + let keyGenPromise = eccGenerator.generateKeyPair(); + keyGenPromise.then( keyPair => { + globalKeyPair = keyPair; + return eccKeyAgreement.generateSecret(keyPair.priKey, keyPair.pubKey); + }).then((secret) => { + console.info("ecdh output is " + secret.data); + }).catch((error) => { + console.error("ecdh error."); + }); +} + +function ecdhCallback() { + let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); + let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256"); + eccGenerator.generateKeyPair(function (err, keyPair) { + globalKeyPair = keyPair; + eccKeyAgreement.generateSecret(keyPair.priKey, keyPair.pubKey, function (err, secret) { + if (err) { + console.error("ecdh error."); + return; + } + console.info("ecdh output is " + secret.data); + }); + }); +} +``` + ## 使用摘要操作 -**场景说明** +### 场景说明 用户指定摘要算法(如SHA256)生成Md实例,并输入单段或多段需要摘要的信息,进行摘要计算更新,并返回消息摘要计算结果,在指定算法后可获取当前算法名与摘要计算长度(字节) @@ -1119,7 +1648,7 @@ function signLongMessagePromise() { 用户指定摘要算法(如SHA256)生成Md实例,并输入单段或多段需要摘要的信息,进行摘要计算更新,并返回消息摘要计算结果,在指定算法后可获取当前算法名与摘要计算长度(字节) -**接口及参数说明** +### 接口及参数说明 详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 @@ -1133,14 +1662,14 @@ function signLongMessagePromise() { | Md | getMdLength() : number; | 获取摘要的长度(由指定的摘要算法决定) | | Md | readonly algName : string; | 获取当前设置的摘要算法名 | -**开发步骤** +### 摘要算法开发步骤 1. 设置算法,通过接口`createMd`生成摘要操作实例 -2. 接受用户数据,通过接口`update`,更新摘要,此步骤可重复 +2. 接受用户数据,通过接口`update`,更新摘要,此步骤可重复,算法库不限制单次update的长度 3. 通过接口`digest`,返回摘要计算结果 4. 获取当前摘要算法名与摘要计算长度 -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" // 可理解的字符串转成字节流 @@ -1212,9 +1741,14 @@ function doMdByCallback() { } ``` -以MD更新时多次调用update实现分段为例: +### 分段摘要算法开发步骤 -```js +1. 设置算法,通过接口`createMd`生成摘要操作实例 +2. 接受用户数据,多次通过接口`update`,更新摘要,实现分段 +3. 通过接口`digest`,返回摘要计算结果 +4. 获取当前摘要算法名与摘要计算长度 + +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" // 可理解的字符串转成字节流 @@ -1273,77 +1807,9 @@ async function doLoopMdPromise() { } ``` -## 使用密钥协商操作 - -**场景说明** - -使用密钥协商操作中,典型的场景有: - -通信双方可以在一个公开的信道上通过相互传送一些消息,共同建立一个安全的共享秘密密钥。 - -**接口及参数说明** - -详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 - -|实例名|接口名|描述| -|---|---|---| -|cryptoFramework|createKeyAgreement(algName : string) : KeyAgreement|根据String设置的参数创建KeyAgreement对象| -|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey, callback : AsyncCallback\) : void|使用callback方式进行密钥协商| -|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey) : Promise\|使用Promise方式进行密钥协商| - -**开发步骤** - -1. 通过createKeyAgreement接口创建KeyAgreement对象,用于后续的密钥协商操作。 -2. 调用KeyAgreement对象提供的generateSecret方法,传入对端的ECC公钥对象,以及本地生成的ECC私钥对象。 - -```js -import cryptoFramework from "@ohos.security.cryptoFramework" - -let globalSelfPriKey; -let globalPeerPubKey; - -function ecdhPromise() { - let peerPubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]); - let peerPubKeyBlob = { data: peerPubKeyArray }; - let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); - let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256"); - eccGenerator.convertKey(peerPubKeyBlob, null).then((peerKeyPair) => { - globalPeerPubKey = peerKeyPair.pubKey; - return eccGenerator.generateKeyPair(); - }).then((keyPair) => { - globalSelfPriKey = keyPair.priKey; - return eccKeyAgreement.generateSecret(globalSelfPriKey, globalPeerPubKey); - }).then((secret) => { - console.info("ecdh promise output is " + secret.data); - }).catch((error) => { - console.error("ecdh error."); - }); -} - -function ecdhCallback() { - let peerPubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]); - let peerPubKeyBlob = { data: peerPubKeyArray }; - let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256"); - let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256"); - eccGenerator.convertKey(peerPubKeyBlob, null, function (err, peerKeyPair) { - globalPeerPubKey = peerKeyPair.pubKey; - eccGenerator.generateKeyPair(function (err, keyPair) { - globalSelfPriKey = keyPair.priKey; - eccKeyAgreement.generateSecret(globalSelfPriKey, globalPeerPubKey, function (err, secret) { - if (err) { - console.error("ecdh error."); - return; - } - console.info("ecdh callback output is " + secret.data); - }); - }); - }) -} -``` - ## 使用消息认证码操作 -**场景说明** +### 场景说明 消息认证码操作主要应用于身份认证的场景: @@ -1351,7 +1817,7 @@ Mac(message authentication code)可以对消息进行完整性校验,通过使 用户指定摘要算法(如SHA256)生成消息认证码Mac实例,输入对称密钥初始化Mac,并传入单段或多段需要摘要的信息,进行消息认证码计算,并获取消息认证码计算结果,在指定算法后可获取当前算法名与消息认证码计算长度(字节)。 -**接口及参数说明** +### 接口及参数说明 详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 @@ -1367,7 +1833,7 @@ Mac(message authentication code)可以对消息进行完整性校验,通过使 | Mac | getMacLength() : number; | 获取MAC的长度(由指定的摘要算法决定) | | Mac | readonly algName : string; | 获取当前设置的摘要算法名 | -**开发步骤** +### HMAC开发步骤 1. 设置算法,通过接口`createMac`生成消息认证码操作实例 2. 接受输入对称密钥,通过接口`init`,初始化Mac @@ -1375,7 +1841,7 @@ Mac(message authentication code)可以对消息进行完整性校验,通过使 4. 通过接口`doFinal`,返回Mac计算结果 5. 获取当前摘要算法名与Mac计算长度 -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" // 可理解的字符串转成字节流 @@ -1435,6 +1901,7 @@ function doHmacByCallback() { try { mac = cryptoFramework.createMac(macAlgName); } catch (error) { + AlertDialog.show({message: "[Callback]: error code: " + error.code + ", message is: " + error.message}); console.error("[Callback]: error code: " + error.code + ", message is: " + error.message); } console.info("[Promise]: Mac algName is: " + mac.algName); @@ -1462,9 +1929,9 @@ function doHmacByCallback() { console.error("[Callback]: err: " + err3.code); } else { macOutput = output; - console.info("[Callback]: HMAC result: " + macOutput.data); + console.error("[Callback]: HMAC result: " + macOutput.data); let macLen = mac.getMacLength(); - console.info("[Callback]: MAC len: " + macLen); + console.error("[Callback]: MAC len: " + macLen); } }); }); @@ -1473,9 +1940,15 @@ function doHmacByCallback() { } ``` +### 分段HMAC开发步骤 以HMAC更新MAC时多次调用update实现分段为例: +1. 设置算法,通过接口`createMac`生成消息认证码操作实例 +2. 接受输入对称密钥,通过接口`init`,初始化Mac +3. 接受数据,多次通过接口`update`,以实现分段: +4. 通过接口`doFinal`,返回Mac计算结果 +5. 获取当前摘要算法名与Mac计算长度 -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" function stringToUint8Array(str) { @@ -1545,36 +2018,37 @@ function doLoopHmacPromise() { } ``` + ## 使用随机数操作 -**场景说明** +### 场景说明 使用随机数操作的主要场景为: -- 用户生成随机数Random实例,输入随机数生成的长度(字节),生成指定长度的随机数。 +- 用户生成随机数Random实例,输入随机数生成的长度(字节),生成指定长度(范围为1~INT_MAX)的安全随机数。 - 用户使用生成的随机数作为参数,进行种子设置。 -**接口及参数说明** - +### 接口及参数说明 详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。 -| 实例名 | 接口名 | 描述 | -| --------------- | ------------------------------------------------------------ | ---------------------------------------------- | -| cryptoFramework | function createRandom() : Random; | 生成随机数Random实例 | -| Random | generateRandom(len : number, callback: AsyncCallback\) : void; | 接受输入长度,通过Callback,异步生成随机数 | -| Random | generateRandom(len : number) : Promise\; | 接受输入长度,通过Promise,异步生成随机数 | -| Random | setSeed(seed : DataBlob) : void; | 接受输入Blob,设置种子 | +| 实例名 | 接口名 | 描述 | +| --------------- | ------------------------------------------------------------ | ------------------------------------------ | +| cryptoFramework | function createRandom() : Random; | 生成随机数Random实例 | +| Random | generateRandom(len : number, callback: AsyncCallback\) : void; | 接受输入长度,通过Callback,异步生成随机数 | +| Random | generateRandom(len : number) : Promise\; | 接受输入长度,通过Promise,异步生成随机数 | +| Random | generateRandomSync(len: number): DataBlob; | 接受输入长度,同步生成随机数 | +| Random | setSeed(seed : DataBlob) : void; | 接受输入Blob,设置种子 | -**开发步骤** +### 开发步骤 1. 通过接口`createRandom`生成随机数操作实例 2. 接受输入长度,通过接口`generateRandom`,生成指定长度的随机数 3. 接受DataBlob数据,通过接口`setSeed`,为随机数生成池设置种子 -```js +```javascript import cryptoFramework from "@ohos.security.cryptoFramework" -// process by promise +// 通过Promise方式生成随机数 function doRandByPromise(len) { var rand; try { @@ -1595,7 +2069,7 @@ function doRandByPromise(len) { }); } -// process by callback +// 通过Callback方式生成随机数 function doRandByCallback(len) { var rand; try { @@ -1616,4 +2090,25 @@ function doRandByCallback(len) { } }); } + +// 通过同步接口生成随机数 +function doRandBySync(len) { + var rand; + try { + rand = cryptoFramework.createRandom(); + } catch (error) { + console.error("[Sync]: error code: " + error.code + ", message is: " + error.message); + } + + try { + let randData = rand.generateRandomSync(len); + if (randData != null) { + console.info("[Sync]: rand result: " + randData.data); + } else { + console.error("[Sync]: get rand result fail!"); + } + } catch (error) { + console.error("[Sync]: error: " + error.message); + } +} ``` diff --git a/zh-cn/application-dev/security/cryptoFramework-overview.md b/zh-cn/application-dev/security/cryptoFramework-overview.md index a039e6eba1..d9ef74fa7a 100644 --- a/zh-cn/application-dev/security/cryptoFramework-overview.md +++ b/zh-cn/application-dev/security/cryptoFramework-overview.md @@ -1,151 +1,221 @@ # 加解密算法库框架概述 - 加解密算法库框架是一个屏蔽了第三方密码学算法库实现差异的算法框架,提供加解密、签名验签、消息验证码、哈希、安全随机数等相关功能。开发者可以通过调用加解密算法库框架,忽略底层不同三方算法库的差异,实现迅捷开发。 -> **说明:** -> -> 加解密算法库框架仅提供密钥的密码学操作,而不提供密钥管理功能。因此,使用算法库时,需要应用自己来保管密钥(适用于临时会话密钥等仅在内存中使用的场景,或者应用自己实现密钥安全存储的场景)。如果业务需要由系统提供密钥管理功能(密钥存储等),请使用[HUKS部件](huks-overview.md)。 +> **说明:** 加解密算法库框架仅提供密钥的密码学操作,而不提供密钥管理功能。因此,使用算法库时,需要应用自己来保管密钥(适用于临时会话密钥等仅在内存中使用的场景,或者应用自己实现密钥安全存储的场景)。如果业务需要由系统提供密钥管理功能(密钥存储等),请使用[HUKS部件](huks-overview.md)。 ## 框架实现原理 加解密算法库框架提供的组件分为三层:接口层,Framework层和插件层。接口层负责对外提供统一的JS接口,插件层实现针对具体三方算法库的功能,Framework层通过灵活加载插件层的插件适配并屏蔽三方算法库差异。 ## 基本概念 - -**对称密钥** +### 对称密钥 对称密钥使用同一个密钥对数据进行加密解密操作。即对称加密算法中,数据发送方使用加密密钥对明文进行特殊加密算法处理后,使其变成复杂的加密密文发送出去。接收方收到密文后,若想解读原文,则需要使用同一个加密密钥以及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。 -- **AES加密** +- **AES密钥** AES的全称是Advanced Encryption Standard,是最常见的对称加密。AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。 +- **3DES密钥** -- **3DES加密** - 3DES,也称为 3DESede 或 TripleDES,是三重数据加密算法,相当于是对每个数据块应用三次DES的对称加密算法,它使用3个64位的密钥对数据块进行三次加密。相比DES,3DES因密钥长度变长,安全性有所提高,但其处理速度不高。因此又出现了AES加密算法,AES较于3DES速度更快、安全性更高。 -**非对称密钥** +### 非对称密钥 非对称密钥使用公钥和私钥两个密钥来进行算法操作,公钥对外公开,私钥对外保密。对于加解密操作,一般使用公钥对明文进行加密形成密文,持有私钥的人即可对密文解密形成明文。对于签名验签操作,使用私钥对明文进行签名,公钥持有者可以通过公钥对签名数据做验签,验证数据是否被篡改。 - **RSA密钥** - RSA密钥以极大整数做因数分解的数学难题作为密钥安全性的基石。生成密钥时,首先需要随机出两个大素数p和q,计算n = p * q并将n做为模,再选择一个大于1且小于(p - 1) * (q - 1)的整数e,确保e与(p - 1)*(q - 1)互素,最后计算d,使得e * d - 1为(p - 1)和(q - 1)的倍数,则可得到公钥(n, e)和私钥(n, d)。 + RSA算法是由Ron Rivest、Adi Shamir和Leonard Adleman一起提出的,是一种非对称加密算法,广泛应用于现代的信息加密传输等领域。它的数学基础是大质数相乘,对其积做因式分解的计算困难性。 + + RSA密钥参数,涉及三个整数,包括: + + n:模数(Modulus),是私钥和公钥的公共参数。 - 算法库框架除提供了默认的双素数RSA密钥生成外,还提供了多素数密钥生成方式,可以在密钥生成时通过指定primes参数(PRIMES_2, PRIMES_3, PRIMES_4, PRIMES_5)指定素数个数。多素数密钥的优点是可以减少解密、签名的计算量(中国剩余定理),但相对的劣势是密钥强度会越低,算法库依据OpenSSL的素数使用规则制定了相应规格,具体将在**约束与限制**章节中说明。 + sk:私钥指数(privateExponent),公式中常写作d。 + + pk:公钥指数(publicExponent),公式中常写作e。 - **ECC密钥** - - ECC是一种基于椭圆曲线数学的公开密钥加密算法,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性,算法库框架提供了多种椭圆曲线的ECC密钥生成能力。 -**加解密** + ECC的全称是Elliptic Curve Cryptography,是一种基于椭圆曲线数学的公开密钥加密算法,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性,算法库框架提供了多种椭圆曲线的ECC密钥生成能力。 + + 椭圆曲线算法可以看作是定义在特殊集合下数的运算,当前算法库支持的是Fp域的椭圆曲线,p为素数,Fp域也称素数域。 + + Fp域下的ECC密钥参数,包括: + + p: 素数,用于确定Fp。 + + a, b: 确定椭圆曲线的方程。 + + g: 椭圆曲线的一个基点(base point),可由gx,gy表示。 + + n: 基点g的阶(order)。 + + h: 余因子(cofactor)。 + + sk: 私钥,是一个随机整数,小于n。 + + pk: 公钥,是椭圆曲线上的一个点, pk = sk * g。 + +- **DSA密钥** + + DSA的全称是Digital Signature Algorithm,是一种基于模算数和整数有限域离散对数难题的一种公开密钥算法,不能用于加解密,一般用于数字签名和验签,算法库框架提供了多种不同长度的DSA密钥生成能力。 + + DSA密钥参数,包括: + + p:一个素模数,比特长度为64的整数倍。 + + q:p-1的素因子,长度与p的长度有关。 + + g:g = (h ^ ((p - 1) / q)) mod p,h为满足1 < h < p -1的任意整数。 + + sk:私钥,为随机生成的整数,满足0 < sk < q。 + + pk:公钥,pk = (g ^ sk) mod p。 + + +### 加解密 - **对称AES加解密** 算法库目前提供了AES加解密常用的7种加密模式:ECB、CBC、OFB、CFB、CTR、GCM和CCM。AES为分组加密算法,分组长度大小为128位。实际应用中明文最后一组可能不足128位,不足数据可以使用各种padding模式做数据填充。下文中描述了各个padding的区别: - - NoPadding:不带填充。 - - PKCS5:填充字符由一个字节序列组成,每个字节填充该填充字节序列的长度,规定是8字节填充。 - - PKCS7:填充字符和PKCS5填充方法一致,但是可以在1-255字节之间任意填充。 + - NoPadding:不带填充; + - PKCS5:填充字符由一个字节序列组成,每个字节填充该填充字节序列的长度,规定是8字节填充; + - PKCS7:填充字符和PKCS5填充方法一致,但是可以在1-255字节之间任意填充; - > **说明:** - > - > ECB、CBC加密模式,明文长度不是128位整数倍,必须使用填充方法补足。
- > 由于需要填充至分组大小,所以实际算法库中的PKCS5和PKCS7都是以分组大小作为填充长度的,即AES加密填充至16字节。 + > **说明:** ECB、CBC加密模式,明文长度不是128位整数倍,必须使用填充方法补足。
由于需要填充至分组大小,所以实际算法库中的PKCS5和PKCS7都是以分组大小作为填充长度的,即AES加密填充至16字节。 - **对称3DES加解密** 该算法的加解密过程分别是对明文/密文数据进行三次DES加密或解密,得到相应的密文或明文。 算法库目前提供了3DES加解密常用的4种加密模式:ECB、CBC、OFB和CFB。DES为分组加密算法,分组长度大小为64位。实际应用中明文最后一组可能不足64位,不足数据可以使用各种padding模式做数据填充。下文中描述了各个padding的区别: - - NoPadding:不带填充。 - - PKCS5:填充字符由一个字节序列组成,每个字节填充该填充字节序列的长度,规定是8字节填充。 - - PKCS7:填充字符和PKCS5填充方法一致,但是可以在1-255字节之间任意填充。 + - NoPadding:不带填充; + - PKCS5:填充字符由一个字节序列组成,每个字节填充该填充字节序列的长度,规定是8字节填充; + - PKCS7:填充字符和PKCS5填充方法一致,但是可以在1-255字节之间任意填充; + + > **说明:** ECB、CBC加密模式,明文长度不是64位整数倍,必须使用填充方法补足。
由于需要填充至分组大小,所以实际算法库中的PKCS5和PKCS7都是以分组大小作为填充长度的,即3DES加密填充至8字节。 - > **说明:** - > - > ECB、CBC加密模式,明文长度不是64位整数倍,必须使用填充方法补足。
- > 由于需要填充至分组大小,所以实际算法库中的PKCS5和PKCS7都是以分组大小作为填充长度的,即3DES加密填充至8字节。 - **非对称RSA加解密** - 当持有RSA公钥(n, e)和私钥(n, d)后,RSA加密过程为:密文 = 明文 ^ e mod n, 解密过程为:明文 = 密文 ^ d mod n。算法库目前提供了RSA加解密常用的三种模式:PKCS1、PKCS1_OAEP和NoPadding。RSA为块加密算法,加密长度需要在固定长度进行,实际应用中会使用各种padding模式做数据填充。下文中描述了各个padding的区别: - - NoPadding:不带填充,输入的数据必须与RSA钥模一样长,输出数据长度与RSA钥模一样长。 - - PKCS1:pkcs1padding V1.5是RSA加解密默认的填充方式,输入的数据必须<=RSA钥模-11,输出数据长度与RSA钥模一样长。 - - PKCS1_OAEP:RSA_PKCS1_OAEP_PADDING填充模式是PKCS#1推出的新填充方式,此模式需要设置两个摘要(md和mgf1_md),输入的数据必须小于RSA钥模 - md摘要长度 - mgf1_md摘要长度 - 2,输出数据长度与RSA钥模一样长。 + RSA为块加密算法,加密长度需要在固定长度进行,实际应用中会使用各种padding模式做数据填充。算法库目前提供了RSA加解密常用的三种模式:NoPadding、PKCS1和PKCS1_OAEP。下文中描述了各个padding的区别: + - NoPadding:不带填充,输入的数据必须与RSA钥模一样长,输出数据长度与RSA钥模一样长; + - PKCS1:即RFC3447规范中的RSAES-PKCS1-V1_5模式(对应于OpenSSL中的RSA_PKCS1_PADDING)在进行RSA运算时需要将源数据D转化为Encryption block(EB),加密时,输入的数据最大长度 <= RSA钥模 - 11,输出数据长度与RSA钥模一样长; + - PKCS1_OAEP:即RFC3447规范中的RSAES-OAEP模式(对应于OpenSSL中的RSA_PKCS1_OAEP_PADDING),是PKCS#1推出的新填充方式,此模式需要设置两个摘要(md和mgf1_md),加密时,输入的数据必须小于RSA钥模 - md摘要长度 - mgf1_md摘要长度 - 2(摘要长度以字节为单位),输出数据长度与RSA钥模一样长;此模式还可额外设置pSource字节流,来定义OAEP填充的编码输入P,并且可以获取PKCS1_OAEP的相关参数。
- > **说明:** - > - > RSA钥模 = (RSA的bits + 7) / 8 + PKCS1_OAEP的相关参数包括: + + md: 摘要算法。 -**签名验签** + mgf: 掩码生成算法,目前仅支持MGF1。 + + mgf1_md: mgf1摘要算法。 + + pSource: 字节流,用于编码输入。 + + > **说明:** RSA钥模 = (RSA的bits + 7) / 8 + +### 签名验签 - **RSA签名验签** - 当持有RSA公钥(n, e)和私钥(n, d)后,RSA签名生成过程为:签名 = 消息 ^ d mod n, 验签过程为:消息 = 签名 ^ d mod n。消息发送方发送数据时,同时发送消息和私钥签名后的签名信息,消息接收方接受到数据后,将签名信息用公钥解密并验证消息是否一致。因发送的消息长度大多大于RSA钥模,因此算法库框架提供了两种padding模式,通过摘要提取消息的散列值再做签名。算法库框架中提供了签名验签相关的两种模式:PKCS1和PSS。下问对两种模式做详细描述: - - PKCS1: pkcs1padding V1.5是RSA加解密默认的填充方式,使用该模式时需要设置摘要(md)。 - - PSS: PSS模式是RSA 算法的基础上叠加上一种填充算法,使用该签名算法时需要使用摘要(md)和掩码函数(mgf1_md)。 + 算法库框架目前提供了两种RSA签名验签的padding模式:PKCS1和PSS。下面对两种模式做详细描述: + - PKCS1: 即RFC3447规范中的RSASSA-PKCS1-V1_5模式(对应于OpenSSL中的RSA_PKCS1_PADDING),在签名验签时,使用该模式时需要设置摘要(md),摘要算法输出的长度(字节)需要小于RSA的钥模; + - PSS: 即RFC3447规范中的RSASSA-PSS模式(对应于OpenSSL中的RSA_PKCS1_PSS_PADDING),此模式需要设置两个摘要(md和mgf1_md),且md和mgf1_md长度之和(字节)需要小于RSA的钥模;此模式还可额外设置以字节为单位的盐长度(saltLen),并且可以获取PSS的相关参数; + + PSS的相关参数包括: + + md: 摘要算法。 + + mgf: 掩码生成算法,目前仅支持MGF1。 + + mgf1_md: MGF1算法中使用的摘要算法。 + saltLen: 盐长度,以字节为单位。 + + trailer_field:用于编码操作的整数,其值只支持为1。 + + > **说明:** RSA钥模 = (RSA的bits + 7) / 8 - **ECDSA** - 椭圆曲线数字签名算法(ECDSA)是基于椭圆曲线密码(ECC)模拟数字签名算法(DSA)。相比普通的离散对数问题(DLP)和大数分解问题(IFP),椭圆曲线密码的单位比特强度要高于其他公钥体制。算法库框架提供了多种椭圆曲线及摘要算法组合的椭圆曲线数字签名算法(ECDSA)能力。 + 椭圆曲线数字签名算法(ECDSA)是基于椭圆曲线密码(ECC)的数字签名算法(DSA)。相比普通的离散对数问题(DLP)和大数分解问题(IFP),椭圆曲线密码的单位比特强度要高于其他公钥体制。算法库框架提供了多种椭圆曲线及摘要算法组合的椭圆曲线数字签名算法(ECDSA)能力。 + +- **DSA** + + 数字签名算法(DSA)的安全性基于整数有限域离散对数问题的困难性,这类签名标准具有较大的兼容性和适用性。 -**密钥协商** +### 密钥协商 - **ECDH** ECDH的全称是椭圆曲线迪菲-赫尔曼秘钥交换,是用来在一个非安全通道中建立起安全的共有加密资料,交换双方可以在不共享任何秘密的情况下协商出一个密钥。算法库框架基于开源算法库提供了多种椭圆曲线的ECDH能力。 -**摘要** +### 摘要 消息摘要MD算法是一种能将任意长度的输入消息,通过哈希算法生成长度固定的摘要的算法。消息摘要算法通过其不可逆的特性能被用于敏感信息的加密。消息摘要算法也被称为哈希算法或单向散列算法。 在摘要算法相同时,生成的摘要值主要有下列特点: -- 当输入消息相同时,生成摘要序列相同。 -- 当输入消息的长度不一致时,生成摘要序列长度固定(摘要长度由算法决定)。 -- 当输入消息不一致时,生成摘要序列几乎不会相同(依然存在相同概率,由摘要长度决定相同概率)。 +- 当输入消息相同时,生成摘要序列相同; +- 当输入消息的长度不一致时,生成摘要序列长度固定(摘要长度由算法决定); +- 当输入消息不一致时,生成摘要序列几乎不会相同(依然存在相同概率,由摘要长度决定相同概率); 消息摘要算法主要分为三类:MD,SHA与MAC(详见HMAC章节) MD算法包括MD2,MD4和MD5。 SHA算法主要包括SHA1,SHA224,SHA256,SHA384,SHA512。 -**消息验证码** +### 消息验证码 HMAC(Hash-based Message Authentication Code)是一种基于密钥的消息认证码算法。HMAC通过指定摘要算法,以通信双方共享密钥与消息作为输入,生成消息认证码用于检验传递报文的完整性,HMAC生成的消息认证码为固定长度。HMAC在消息摘要算法的基础上增加了密钥的输入,确保了信息的正确性。 -**随机数** +### 随机数 随机数在加解密过程中主要用于临时会话密钥的生成与非对称加密算法中密钥的生成。随机数由硬件生成的硬件随机数生成器或由软件生成的伪随机数生成器进行生成。在加解密的场景中,安全随机数生成器需要具备随机性,不可预测性,与不可重现性。密码学安全伪随机数生成器CSPRNG(Cryptography Secure Random Number Generators)生成的随机数满足密码学安全伪随机性 - **内部状态**代表随机数生成器内存中的数值,当内部状态相同时,随机数生成器会生成固定的随机数序列 - **种子**(seed)是一个用来对伪随机数的内部状态进行初始化的数据,随机数生成器通过种子来生成一系列的随机序列。 + ## 约束与限制 - 算法库框架不支持多线程并发操作。 - 算法库当前只支持OpenSSL。 +- 使用密钥参数生成密钥时,用到的bigint类型需要以大端的形式输入,且必须为正数。 +- 加解密算法库提供常用算法,其中有部分算法和规格并不适用于安全场景,如MD5等,用户需要根据使用需求选择适合的算法。 + +## 密钥生成规格 -### 密钥生成规格 +密钥生成有两种指定规格的方式:字符串参数 / 密钥参数。 +- 字符串参数:以字符串的形式描述用户想要生成的密钥规格。 +- 密钥参数:使用密钥的详细密码学信息,构造密钥对象。 -**对称密钥生成规格** +### AES密钥生成规格 -- 支持的对称密钥生成参数: +- 支持以字符串参数来生成AES密钥,其生成参数如下表所示: |对称密钥算法|密钥长度(bit)|字符串参数| |---|---|---| - |3DES|192|3DES192| |AES|128|AES128| |AES|192|AES192| |AES|256|AES256| - > **说明:** - > - > “字符串参数”是“对称密钥算法”和“密钥长度”拼接而成,用于在创建对称密钥生成器时,指定密钥规格。 + > **说明**:“字符串参数”是“对称密钥算法”和“密钥长度”拼接而成,用于在创建对称密钥生成器时,指定密钥规格。 + +### 3DES密钥生成规格 + +- 支持以字符串参数来生成3DES密钥,其生成参数如下表所示: + + |对称密钥算法|密钥长度(bit)|字符串参数| + |---|---|---| + |3DES|192|3DES192| -**非对称密钥生成规格** + > **说明**:“字符串参数”是“对称密钥算法”和“密钥长度”拼接而成,用于在创建对称密钥生成器时,指定密钥规格。 -- **RSA密钥生成** +### RSA密钥生成规格 + > **说明**:
+ > 从API version 10开始, 支持使用密钥参数来生成RSA密钥。 - 支持的非对称密钥生成参数: +- 支持以字符串参数来生成RSA密钥,其生成参数如下表所示: - |非对称密钥类型|素数个数|字符串参数| + |RSA密钥类型|素数个数|字符串参数| |---|---|---| |RSA512|2|RSA512\|PRIMES_2| |RSA768|2|RSA768\|PRIMES_2| @@ -163,28 +233,102 @@ HMAC(Hash-based Message Authentication Code)是一种基于密钥的消息 |RSA8192|4|RSA8192\|PRIMES_4| |RSA8192|5|RSA8192\|PRIMES_5| - > **说明:** - > - > 生成RSA非对称密钥时,默认素数为2,PRIMES_2参数可省略。 + > **说明**:“字符串参数”是“RSA密钥类型”和“素数个数”拼接而成,用于在创建非对称密钥生成器时,指定密钥规格。生成RSA非对称密钥时,默认素数为2,PRIMES_2参数可省略。 -- **ECC密钥生成** +- 支持以密钥参数来生成RSA密钥,其密钥参数种类和各个密钥参数的密码学规格要求如下表所示: + | |公共参数|公钥参数|私钥参数|公私钥对参数| + |---|---------|---|---|---| + |n |× |√ |× |√ | + |pk| |√ | |√ | + |sk| | |× |√ | - 支持的非对称密钥生成参数: + > **说明**:密钥参数用于在创建非对称密钥生成器时,指定密钥规格。
+ > 上表说明了算法库对于指定公/私钥参数生成RSA密钥的支持情况。
+ 打√的表示需要指定这一列中的具体属性,来构成密钥参数。
+ 打×的表示这一列中的具体属性对应于某种密钥参数,但是算法库当前不支持通过该密钥参数生成密钥。 - |非对称密钥算法|密钥长度| - |---|---| - |ECC|ECC224| - |ECC|ECC256| - |ECC|ECC384| - |ECC|ECC521| + > **注意**: + > 1. RSA不支持通过指定公共参数(n)来随机生成密钥。
+ > 2. RSA不支持通过指定私钥参数(n, sk)来生成私钥。 -### 加解密规格 +### ECC密钥生成规格 -**对称加解密** + > **说明**:
+ > 从API version 10开始, 支持使用密钥参数来生成ECC密钥。 +- 支持以字符串参数来生成ECC密钥,其生成参数如下表所示: -- 支持的对称加密算法: + |非对称密钥算法|密钥长度(bit)|曲线名|字符串参数| + |---|---|---|---| + |ECC|224|NID_secp224r1|ECC224| + |ECC|256|NID_X9_62_prime256v1|ECC256| + |ECC|384|NID_secp384r1|ECC384| + |ECC|521|NID_secp521r1|ECC521| + + > **说明**:“字符串参数”是“非对称密钥算法”和“密钥长度”拼接而成,用于在创建非对称密钥生成器时,指定密钥规格。
+ > 当前支持的ECC均为Fp域曲线。 + + +- 支持以密钥参数来生成ECC密钥,其密钥参数种类和各个密钥参数的密码学规格要求如下表所示: + | |公共参数|公钥参数|私钥参数|公私钥对参数| + |---|---|---|---|---| + |fieldType| √| √| √| √| + |p | √| √| √| √| + |a | √| √| √| √| + |b | √| √| √| √| + |g | √| √| √| √| + |n | √| √| √| √| + |h | √| √| √| √| + |pk | | √| | √| + |sk | | | √| √| + + > **说明**:密钥参数用于在创建非对称密钥生成器时,指定密钥规格。
+ > 上表说明了算法库对于指定公/私钥参数生成ECC密钥的支持情况。
+ > 打√的表示需要指定这一列中的具体属性,来构成密钥参数。 + + > **注意**: + > 1. 当前ECC只支持Fp域,因此fieldType固定为"Fp"。fieldType和p构成了属性field,当前field只支持[ECFieldFp](../reference/apis/js-apis-cryptoFramework.md#ecfieldfp10)。
+ > 2. g和pk为ECC曲线上的点,属于[Point](../reference/apis/js-apis-cryptoFramework.md#point10)类型,需要指定具体X,Y坐标。 + +### DSA密钥生成规格 + > **说明**:
+ > 从API version 10开始, 支持DSA算法,包括密钥生成和签名验签。 + +- 支持以字符串参数来生成DSA密钥,其生成参数如下表所示: + + |非对称密钥算法|密钥长度(bit)|字符串参数| + |---|---|---| + |DSA|1024|DSA1024| + |DSA|2048|DSA2048| + |DSA|3072|DSA3072| + + > **说明**:“字符串参数”是“非对称密钥算法”和“密钥长度”拼接而成,用于在创建非对称密钥生成器时,指定密钥规格。
+ +- 支持以密钥参数来生成RSA密钥,其密钥参数种类和各个密钥参数的密码学规格要求如下表所示: + | |公共参数|公钥参数|私钥参数|公私钥对参数| + |---|---------|---|---|---| + |p |√ |√ |× |√ | + |q |√ |√ |× |√ | + |g |√ |√ |× |√ | + |pk | |√ | |√ | + |sk | | |× |√ | + + > **说明**:密钥参数用于在创建非对称密钥生成器时,指定密钥规格。
+ > 上表说明了算法库对于指定公/私钥参数生成DSA密钥的支持情况。
+ 打√的表示需要指定这一列中的具体属性,来构成密钥参数。
+ 打×的表示这一列中的具体属性对应于某种密钥参数,但是算法库当前不支持通过该密钥参数生成密钥。 - |对称加解密算法|分组模式| 字符串参数 | + > **注意**: + > 1. DSA不支持通过指定私钥参数(p, q, g, sk)来生成私钥。
+ > 2. 当使用公共参数(p, q, g)来生成DSA密钥对时,DSA密钥长度至少需要1024位。 + + +## 加解密规格 +### 对称加解密 + > **说明**:
+ > 从API version 10开始, 支持对称加解密不带密钥长度的规格。 + +- 支持的对称加密算法: + |对称加解密算法|分组模式|字符串参数 | |---|---|---| |3DES|ECB|3DES192\|ECB\|[NoPadding\|PKCS5\|PKCS7]| |3DES|CBC|3DES192\|CBC\|[NoPadding\|PKCS5\|PKCS7]| @@ -203,10 +347,11 @@ HMAC(Hash-based Message Authentication Code)是一种基于密钥的消息 > 1. []中只能任选一项。 > 2. “字符串参数”是“对称加解密算法(含密钥长度)”、“分组模式”、“填充模式”拼接而成,用于在创建对称加解密实例时,指定对称加解密算法规格。 -**非对称RSA加解密** +### 非对称RSA加解密 + > **说明**:
+ > 从API version 10开始, 支持非对称RSA加解密不带密钥长度的规格。 RSA加解密时,涉及三种填充模式:NoPadding, PKCS1和PKCS1_OAEP。 - - 使用NoPadding模式时可以指定的参数: |非对称密钥类型| 填充模式 | 字符串参数 | @@ -218,6 +363,12 @@ RSA加解密时,涉及三种填充模式:NoPadding, PKCS1和PKCS1_OAEP。 |RSA3072|NoPadding|RSA3072\|NoPadding| |RSA4096|NoPadding|RSA4096\|NoPadding| |RSA8192|NoPadding|RSA8192\|NoPadding| + |RSA|NoPadding|RSA\|NoPadding| + + > **说明:** + > + > 1. “字符串参数”是“非对称密钥类型”、“填充模式”拼接而成,用于在创建非对称加解密实例时,指定非对称加解密算法规格。 + > 2. 在上表最后一行,为了兼容由密钥参数生成的密钥,RSA加解密参数输入密钥类型时支持不带长度,加解密运算取决于实际输入的密钥长度。 - 使用PKCS1模式时可以指定的参数: @@ -230,14 +381,14 @@ RSA加解密时,涉及三种填充模式:NoPadding, PKCS1和PKCS1_OAEP。 |RSA3072|PKCS1|RSA3072\|PKCS1| |RSA4096|PKCS1|RSA4096\|PKCS1| |RSA8192|PKCS1|RSA8192\|PKCS1| - -- 使用PKCS1_OAEP模式时可以指定的参数: + |RSA|PKCS1|RSA\|PKCS1| > **说明:** > - > 1. []内的参数只能任选一项,非[]内的为固定值; - > 2. 使用时请从表格中选择非对称密钥类型、填充模式、摘要、掩码摘要四个数据,用|拼接成字符串。
- > 例如:"RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA256" + > 1. “字符串参数”是“非对称密钥类型”、“填充模式”拼接而成,用于在创建非对称加解密实例时,指定非对称加解密算法规格。 + > 2. 在上表最后一行,为了兼容由密钥参数生成的密钥,RSA加解密参数输入密钥类型时支持不带长度,加解密运算取决于实际输入的密钥长度。 + +- 使用PKCS1_OAEP模式时可以指定的参数: | 非对称密钥类型 | 填充模式 | 摘要 | 掩码摘要 | |---|---|---|---| @@ -278,34 +429,56 @@ RSA加解密时,涉及三种填充模式:NoPadding, PKCS1和PKCS1_OAEP。 |RSA8192|PKCS1_OAEP|MD5|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| |RSA8192|PKCS1_OAEP|SHA1|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| |RSA8192|PKCS1_OAEP|SHA224|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| - |RSA8192|PKCS1_OAEP|SHA256|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512 ]| + |RSA8192|PKCS1_OAEP|SHA256|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| |RSA8192|PKCS1_OAEP|SHA384|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| |RSA8192|PKCS1_OAEP|SHA512|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| + |RSA|PKCS1_OAEP|符合长度要求的摘要算法|MGF1_符合长度要求的摘要算法| + + > **说明:** + > + > 1. []内的参数只能任选一项,非[]内的为固定值; + > 2. 使用时请从表格中选择非对称密钥类型、填充模式、摘要、掩码摘要四个数据,用|拼接成“字符串参数”,用于在创建非对称加解密实例时,指定非对称加解密算法规格。 + > 例如:"RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA256" + > 3. 在上表最后一行,为了兼容由密钥参数生成的密钥,RSA加解密参数输入密钥类型时支持不带长度,加解密运算取决于实际输入的密钥长度。 + > 4. 输入的数据必须小于RSA钥模 - md摘要长度 - mgf1_md摘要长度 - 2,如RSA密钥为512位时,不支持SHA512,RSA钥模和摘要长度定义,详见[加解密](#加解密)中RSA的相关描述。 -### 签名验签规格 +- 使用PKCS1_OAEP模式时,可以通过获取加解密OAEP填充模式的各个[参数](../reference/apis/js-apis-cryptoFramework.md#cipherspecitem10),并设置OAEP填充的编码输入P。 + | OAEP参数 |枚举值| 获取 | 设置 | + |---|---|---|---| + |md|OAEP_MD_NAME_STR |√|| + |mgf|OAEP_MGF_NAME_STR|√|| + |mgf1_md|OAEP_MGF1_MD_STR |√|| + |pSource|OAEP_MGF1_PSRC_UINT8ARR|√|√| -**RSA签名验签** + > **说明**:
+ > 上表说明了算法库对于OAEP参数的获取和设置支持情况,打√的表示需要对该参数具有获取或设置的能力。 -RSA签名验签时,涉及两种填充模式:PKCS1和PSS。 +## 签名验签规格 -- 使用PKCS1模式时可以指定的参数: +### RSA签名验签 + > **说明**:
+ > 从API version 10开始, 支持RSA签名验签不带密钥长度的规格。 + +RSA签名验签时,涉及两种填充模式:PKCS1和PSS。 +- 使用PKCS1模式时可以指定的参数: | 非对称密钥类型 | 填充模式 | 摘要 | 字符串参数 | |---|---|---|---| - |RSA512|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384]|RSA512\|PKCS1\| [MD5\|SHA1\|SHA224\|SHA256\|SHA384]| + |RSA512|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384]|RSA512\|PKCS1\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384]| |RSA768|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|RSA768\|PKCS1\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| |RSA1024|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|RSA1024\|PKCS1\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| |RSA2048|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|RSA2048\|PKCS1\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| |RSA3072|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|RSA3072\|PKCS1\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| |RSA4096|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|RSA4096\|PKCS1\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| |RSA8192|PKCS1|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|RSA8192\|PKCS1\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |RSA|PKCS1|符合长度要求的摘要算法|RSA\|PKCS1\|符合长度要求的摘要算法| -- 使用PSS模式时可以指定的参数: > **说明:** - > > 1. []内的参数只能任选一项,非[]内的为固定值; - > 2. 使用时请从表格中选择非对称密钥类型、填充模式、摘要、掩码摘要四个数据,用|拼接成字符串。
- > 例如:"RSA2048|PSS|SHA256|MGF1_SHA256" + > 2. 在上表最后一行,为了兼容由密钥参数生成的密钥,RSA签名验签参数输入密钥类型时支持不带长度,签名验签运算取决于实际输入的密钥长度。 + > 3. RSA签名验签时,摘要算法输出的长度,需要小于RSA的钥模, 如RSA密钥为512位时,不支持SHA512,详见[签名验签](#签名验签)中RSA的相关描述。 + +- 使用PSS模式时可以指定的参数: | 非对称密钥类型 | 填充模式 | 摘要 | 掩码摘要 | |---|---|---|---| @@ -348,42 +521,89 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。 |RSA8192|PSS|SHA224|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| |RSA8192|PSS|SHA256|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| |RSA8192|PSS|SHA384|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| - |RSA8192|PSS|SHA512| [MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| + |RSA8192|PSS|SHA512|[MGF1_MD5\|MGF1_SHA1\|MGF1_SHA224\|MGF1_SHA256\|MGF1_SHA384\|MGF1_SHA512]| + |RSA|PSS|符合长度要求的摘要算法|MGF1_符合长度要求的摘要算法| -**ECDSA签名验签** + > **说明:** + > + > 1. []内的参数只能任选一项,非[]内的为固定值; + > 2. 使用时请从表格中选择非对称密钥类型、填充模式、摘要、掩码摘要四个数据,用|拼接成“字符串参数”,用于在创建非对称签名验签实例时,指定非对称签名验签算法规格。 + > 例如:"RSA2048|PSS|SHA256|MGF1_SHA256" + > 3. 在上表最后一行,为了兼容由密钥参数生成的密钥,RSA签名验签参数输入密钥类型时支持不带长度,签名验签运算取决于实际输入的密钥长度。 + > 4. RSA签名验签时,对于PSS模式,md和mgf1_md长度之和(字节)需要小于RSA的钥模。如RSA密钥为512位时,无法支持md和mgf1_md同时为SHA256。RSA钥模和摘要长度定义,详见[签名验签](#签名验签)中RSA的相关描述。 +- 使用PSS模式时,可以通过获取签名验签PSS填充模式的各个[参数](../reference/apis/js-apis-cryptoFramework.md#signspecitem10),并设置PSS的以字节为单位的盐长度(saltLen)。 + | PSS参数 |枚举值| 获取 | 设置 | + |---|---|---|---| + |md|PSS_MD_NAME_STR |√|| + |mgf|PSS_MGF_NAME_STR|√|| + |mgf1_md|PSS_MGF1_MD_STR |√|| + |saltLen|PSS_SALT_LEN_NUM|√|√| + |trailer_field|PSS_TRAILER_FIELD_NUM|√|| + + > **说明**:
+ > 上表说明了算法库对于PSS参数的获取和设置支持情况,打√的表示需要对该参数具有获取或设置的能力。 + +### ECDSA签名验签 + > **说明**:
+ > 从API version 10开始, 支持ECDSA签名验签不带密钥长度的规格。 - 支持的ECDSA参数: - |非对称密钥算法|支持种类| - |---|---| - |ECC|ECC224| - |ECC|ECC256| - |ECC|ECC384| - |ECC|ECC521| + |非对称密钥类型|摘要|字符串参数| + |---|---|---| + |ECC224|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|ECC224\|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |ECC256|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|ECC256\|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |ECC384|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|ECC384\|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |ECC521|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|ECC521\|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |ECC|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|ECC\|[SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| - |摘要算法|支持种类| - |---|---| - |HASH|SHA1| - |HASH|SHA224| - |HASH|SHA256| - |HASH|SHA384| - |HASH|SHA512| + > **说明:** + > 1. []内的参数只能任选一项,非[]内的为固定值; + > 2. 使用时请从表格中选择非对称密钥类型、摘要二个数据,用|拼接成“字符串参数”,用于在创建非对称签名验签实例时,指定非对称签名验签算法规格。 + > 例如:"ECC224|SHA256" + > 3. 在上表最后一行,为了兼容由密钥参数生成的密钥,ECDSA签名验签参数输入密钥类型时支持不带长度,签名验签运算取决于实际输入的密钥长度。 + +### DSA签名验签 + > **说明**:
+ > 从API version 10开始, 支持DSA签名验签规格。 + +- 支持的DSA参数: + + |非对称密钥类型|摘要|字符串参数| + |---|---|---| + |DSA1024|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|DSA1024\|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |DSA2048|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|DSA2048\|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |DSA3072|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|DSA3072\|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + |DSA|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]|DSA\|[NoHash\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512]| + + > **说明:** + > 1. []内的参数只能任选一项,非[]内的为固定值; + > 2. 使用时请从表格中选择非对称密钥类型、摘要二个数据,用|拼接成“字符串参数”,用于在创建非对称签名验签实例时,指定非对称签名验签算法规格。 + > 例如:"DSA1024|SHA256" + > 3. 在上表最后一行,为了兼容由密钥参数生成的密钥,DSA签名验签参数输入密钥类型时支持不带长度,签名验签运算取决于实际输入的密钥长度。 -### 密钥协商规格 +## 密钥协商规格 -**ECDH** +### ECDH + > **说明**:
+ > 从API version 10开始, 支持ECDH不带密钥长度的规格。 - 支持的ECDH参数: - |非对称密钥算法|支持种类| + |非对称密钥算法|字符串参数| |---|---| |ECC|ECC224| |ECC|ECC256| |ECC|ECC384| |ECC|ECC521| + |ECC|ECC| + + > **说明:** + > 1. “字符串参数”,用于在创建密钥协商时,指定密钥协商算法规格。 + > 2. 在上表最后一行,为了兼容由密钥参数生成的密钥,ECDH密钥协商参数输入密钥类型时支持不带长度,密钥协商运算取决于实际输入的密钥长度。 -### MD消息摘要算法规格 +## MD消息摘要算法规格 - 加解密算法库框架当前支持的MD算法参数: |摘要算法|支持种类| @@ -395,8 +615,10 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。 |HASH|SHA512| |HASH|MD5| -### HMAC消息认证码算法规格 + > **说明:** + > “支持种类”,用于在创建MD消息摘要时,指定MD消息摘要算法规格。 +## HMAC消息认证码算法规格 - 加解密算法库框架当前支持的HMAC算法参数: |摘要算法|支持种类| @@ -406,3 +628,13 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。 |HASH|SHA256| |HASH|SHA384| |HASH|SHA512| + + > **说明:** + > “支持种类”,用于在创建HMAC消息认证码时,指定HMAC消息认证码算法规格。 + +## 随机数 +- 加解密算法库框架支持随机数生成算法,目前只支持“CTR_DRBG"算法规格 + + > **说明:** + > 1. 随机数生成算法目前支持生成长度为[1, INT_MAX]的安全随机数,长度单位为byte。 + > 2. 随机数生成算法使用openssl的RAND_priv_bytes接口生成安全随机数。 \ No newline at end of file -- GitLab