未验证 提交 c358a124 编写于 作者: O openharmony_ci 提交者: Gitee

!20413 [新需求]: 算法库国密部分doc资料上库

Merge pull request !20413 from wutiantian_gitee/master
......@@ -58,12 +58,11 @@ function generateAsyKey() {
// Use the key generator to randomly generate an asymmetric key pair.
let keyGenPromise = rsaGenerator.generateKeyPair();
keyGenPromise.then( keyPair => {
globalKeyPair = keyPair;
let pubKey = globalKeyPair.pubKey;
let priKey = globalKeyPair.priKey;
let pubKey = keyPair.pubKey;
let priKey = keyPair.priKey;
// Obtain the binary data of the asymmetric key pair.
pkBlob = pubKey.getEncoded();
skBlob = priKey.getEncoded();
let pkBlob = pubKey.getEncoded();
let skBlob = priKey.getEncoded();
AlertDialog.show({ message : "pk bin data" + pkBlob.data} );
AlertDialog.show({ message : "sk bin data" + skBlob.data} );
})
......@@ -145,7 +144,7 @@ function convertEccAsyKey() {
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"});
......@@ -884,7 +883,7 @@ function stringToUint8Array(str) {
}
// Encrypt the message in promise mode.
function encryptMessageProMise() {
function encryptMessagePromise() {
// Create an AsyKeyGenerator instance.
let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
// Create a Cipher instance.
......@@ -927,7 +926,7 @@ function encryptMessageCallback() {
}
// Encrypt and decrypt the message in promise mode.
function decryptMessageProMise() {
function decryptMessagePromise() {
// Create an AsyKeyGenerator instance.
let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
// Create a Cipher instance for encryption.
......
......@@ -58,7 +58,7 @@ buffer数组。
| 名称 | 类型 | 可读 | 可写 | 说明 |
| ---- | --------------------- | ---- | ---- | ------------------------------------------------------------ |
| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv。常见取值如下:<br/>- AES的CBC\|CTR\|OFB\|CFB模式:iv长度为16字节<br/>- 3DES的CBC\|OFB\|CFB模式:iv长度为8字节 |
| iv | [DataBlob](#datablob) | 是 | 是 | 指明加解密参数iv。常见取值如下:<br/>- AES的CBC\|CTR\|OFB\|CFB模式:iv长度为16字节<br/>- 3DES的CBC\|OFB\|CFB模式:iv长度为8字节<br/>- SM4<sup>10+</sup>的CBC\|CTR\|OFB\|CFB模式:iv长度为16字节。 |
> **说明:**
>
......@@ -1297,7 +1297,7 @@ createCipher(transformation: string): Cipher
> **说明:**
>
> 1. 目前对称加解密中,PKCS5和PKCS7的实现相同,其padding长度和分组长度保持一致(即PKCS5和PKCS7在3DES中均按照8字节填充,在AES中均按照16字节填充),另有NoPadding表示不填充。<br/>开发者需要自行了解密码学不同分组模式的差异,以便选择合适的参数规格。例如选择ECB和CBC模式时,建议启用填充,否则必须确保明文长度是分组大小的整数倍;选择其他模式时,可以不启用填充,此时密文长度和明文长度一致(即可能不是分组大小的整数倍)。
> 2. 使用RSA进行非对称加解密时,必须创建两个Cipher对象分别进行加密和解密操作,而不能对同一个Cipher对象进行加解密。对称加解密没有此要求(即只要算法规格一样,可以对同一个Cipher对象进行加解密操作)。
> 2. 使用RSA、SM2进行非对称加解密时,必须创建两个Cipher对象分别进行加密和解密操作,而不能对同一个Cipher对象进行加解密。对称加解密没有此要求(即只要算法规格一样,可以对同一个Cipher对象进行加解密操作)。
**返回值:**
......@@ -1335,7 +1335,7 @@ try {
一次完整的加/解密流程在对称加密和非对称加密中略有不同:
- 对称加解密:init为必选,update为可选(且允许多次update加/解密大数据),doFinal为必选;doFinal结束后可以重新init开始新一轮加/解密流程。
- RSA非对称加解密:init为必选,不支持update操作,doFinal为必选(允许连续多次doFinal加/解密大数据);RSA不支持重复init,切换加解密模式或填充方式时,需要重新创建Cipher对象。
- RSA、SM2非对称加解密:init为必选,不支持update操作,doFinal为必选(允许连续多次doFinal加/解密大数据);RSA不支持重复init,切换加解密模式或填充方式时,需要重新创建Cipher对象。
### 属性
......@@ -1447,7 +1447,7 @@ update(data: DataBlob, callback: AsyncCallback\<DataBlob>): void
> 2. 根据数据量,可以不调用update(即[init](#init-2)完成后直接调用[doFinal](#dofinal-2))或多次调用update。<br/>
> 算法库目前没有对update(单次或累计)的数据量设置大小限制,建议对于大数据量的对称加解密,采用多次update的方式传入数据。<br/>
> AES使用多次update操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。
> 3. RSA非对称加解密不支持update操作。
> 3. RSA、SM2非对称加解密不支持update操作。
**系统能力:** SystemCapability.Security.CryptoFramework
......@@ -1508,7 +1508,7 @@ update(data: DataBlob): Promise\<DataBlob>
> 2. 根据数据量,可以不调用update(即[init](#init-2)完成后直接调用[doFinal](#dofinal-2))或多次调用update。<br/>
> 算法库目前没有对update(单次或累计)的数据量设置大小限制,建议对于大数据量的对称加解密,可以采用多次update的方式传入数据。<br/>
> AES使用多次update操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。
> 3. RSA非对称加解密不支持update操作。
> 3. RSA、SM2非对称加解密不支持update操作。
**系统能力:** SystemCapability.Security.CryptoFramework
......@@ -1570,14 +1570,14 @@ doFinal(data: DataBlob, callback: AsyncCallback\<DataBlob>): void
- 对于GCM和CCM模式的对称加密:一次加密流程中,如果将每一次update和doFinal的结果拼接起来,会得到“密文+authTag”,即末尾的16字节(GCM模式)或12字节(CCM模式)是authTag,而其余部分均为密文。(也就是说,如果doFinal的data参数传入null,则doFinal的结果就是authTag)<br/>authTag需要填入解密时的[GcmParamsSpec](#gcmparamsspec)[CcmParamsSpec](#ccmparamsspec);密文则作为解密时的入参data。
- 对于其他模式的对称加解密、GCM和CCM模式的对称解密:一次加/解密流程中,每一次update和doFinal的结果拼接起来,得到完整的明文/密文。
(2)在RSA非对称加解密中,doFinal加/解密本次传入的数据,通过注册回调函数获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。
(2)在RSA、SM2非对称加解密中,doFinal加/解密本次传入的数据,通过注册回调函数获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。
> **说明:**
>
> 1. 对称加解密中,调用doFinal标志着一次加解密流程已经完成,即[Cipher](#cipher)实例的状态被清除,因此当后续开启新一轮加解密流程时,需要重新调用[init()](init-2)并传入完整的参数列表进行初始化<br/>(比如即使是对同一个Cipher实例,采用同样的对称密钥,进行加密然后解密,则解密中调用init的时候仍需填写params参数,而不能直接省略为null)。
> 2. 如果遇到解密失败,需检查加解密数据和[init](#init-2)时的参数是否匹配,包括GCM模式下加密得到的authTag是否填入解密时的GcmParamsSpec等。
> 3. doFinal的结果可能为null,因此使用.data字段访问doFinal结果的具体数据前,请记得先判断结果是否为null,避免产生异常。
> 4. RSA非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。
> 4. RSA、SM2非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。
**系统能力:** SystemCapability.Security.CryptoFramework
......@@ -1626,14 +1626,14 @@ doFinal(data: DataBlob): Promise\<DataBlob>
- 对于GCM和CCM模式的对称加密:一次加密流程中,如果将每一次update和doFinal的结果拼接起来,会得到“密文+authTag”,即末尾的16字节(GCM模式)或12字节(CCM模式)是authTag,而其余部分均为密文。(也就是说,如果doFinal的data参数传入null,则doFinal的结果就是authTag)<br/>authTag需要填入解密时的[GcmParamsSpec](#gcmparamsspec)[CcmParamsSpec](#ccmparamsspec);密文则作为解密时的入参data。
- 对于其他模式的对称加解密、GCM和CCM模式的对称解密:一次加/解密流程中,每一次update和doFinal的结果拼接起来,得到完整的明文/密文。
(2)在RSA非对称加解密中,doFinal加/解密本次传入的数据,通过Promise获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。
(2)在RSA、SM2非对称加解密中,doFinal加/解密本次传入的数据,通过Promise获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。
> **说明:**
>
> 1. 对称加解密中,调用doFinal标志着一次加解密流程已经完成,即[Cipher](#cipher)实例的状态被清除,因此当后续开启新一轮加解密流程时,需要重新调用[init()](init-2)并传入完整的参数列表进行初始化<br/>(比如即使是对同一个Cipher实例,采用同样的对称密钥,进行加密然后解密,则解密中调用init的时候仍需填写params参数,而不能直接省略为null)。
> 2. 如果遇到解密失败,需检查加解密数据和[init](#init-2)时的参数是否匹配,包括GCM模式下加密得到的authTag是否填入解密时的GcmParamsSpec等。
> 3. doFinal的结果可能为null,因此使用.data字段访问doFinal结果的具体数据前,请记得先判断结果是否为null,避免产生异常。
> 4. RSA非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。
> 4. RSA、SM2非对称加解密时多次doFinal操作的示例代码详见开发指导“[使用加解密操作](../../security/cryptoFramework-guidelines.md#使用加解密操作)”。
**系统能力:** SystemCapability.Security.CryptoFramework
......@@ -1820,7 +1820,7 @@ Sign实例生成。<br/>支持的规格详见框架概述“[签名验签规格]
| 参数名 | 类型 | 必填 | 说明 |
| ------- | ------ | ---- | ------------------------------------------------------------ |
| algName | string | 是 | 指定签名算法:RSA,ECC或DSA。使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要。 |
| algName | string | 是 | 指定签名算法:RSA,ECC,DSA或SM2<sup>10+</sup>。使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要。 |
**返回值**
......@@ -2207,7 +2207,7 @@ Verify实例生成。<br/>支持的规格详见框架概述“[签名验签规
| 参数名 | 类型 | 必填 | 说明 |
| ------- | ------ | ---- | ------------------------------------------------------------ |
| algName | string | 是 | 指定签名算法:RSA,ECC或DSA。使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要。 |
| algName | string | 是 | 指定签名算法:RSA,ECC,DSA或SM2<sup>10+</sup>。使用RSA PKCS1模式时需要设置摘要,使用RSA PSS模式时需要设置摘要和掩码摘要。 |
**返回值**
......
......@@ -60,12 +60,11 @@ function generateAsyKey() {
// 通过非对称密钥生成器,随机生成非对称密钥
let keyGenPromise = rsaGenerator.generateKeyPair();
keyGenPromise.then( keyPair => {
globalKeyPair = keyPair;
let pubKey = globalKeyPair.pubKey;
let priKey = globalKeyPair.priKey;
let pubKey = keyPair.pubKey;
let priKey = keyPair.priKey;
// 获取非对称密钥的二进制数据
pkBlob = pubKey.getEncoded();
skBlob = priKey.getEncoded();
let pkBlob = pubKey.getEncoded();
let skBlob = priKey.getEncoded();
AlertDialog.show({ message : "pk bin data" + pkBlob.data} );
AlertDialog.show({ message : "sk bin data" + skBlob.data} );
})
......@@ -147,7 +146,7 @@ function convertEccAsyKey() {
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"});
......@@ -209,6 +208,106 @@ function testConvertAesKey() {
}
```
### 随机生成SM2密钥对,并获得二进制数据
> **说明:**
>
> 从API version 10开始, 支持SM2非对称密钥随机生成。
示例6:随机生成非对称密钥KeyPair,并获得二进制数据(场景1、3)
1. 创建非对称密钥生成器。
2. 通过非对称密钥生成器随机生成非对称密钥。
3. 获取密钥对象的二进制数据。
以使用Promise方式随机生成SM2密钥(256位)为例:
```js
import cryptoFramework from '@ohos.security.cryptoFramework';
function generateAsyKey() {
// 创建非对称密钥生成器
let rsaGenerator = cryptoFramework.createAsyKeyGenerator("SM2_256");
// 通过非对称密钥生成器,随机生成非对称密钥
let keyGenPromise = rsaGenerator.generateKeyPair();
keyGenPromise.then( keyPair => {
let pubKey = keyPair.pubKey;
let priKey = keyPair.priKey;
// 获取非对称密钥的二进制数据
let pkBlob = pubKey.getEncoded();
let skBlob = priKey.getEncoded();
AlertDialog.show({ message : "pk bin data" + pkBlob.data} );
AlertDialog.show({ message : "sk bin data" + skBlob.data} );
})
}
```
### 随机生成SM4密钥,并获得二进制数据
> **说明:**
>
> 从API version 10开始, 支持SM4密钥随机生成。
示例7:随机生成对称密钥SymKey,并获得二进制数据(场景1、3)
1. 创建对称密钥生成器。
2. 通过对称密钥生成器随机生成对称密钥。
3. 获取算法库密钥对象的二进制数据。
以使用Promise方式随机生成SM4密钥(128位)为例:
```js
import cryptoFramework from '@ohos.security.cryptoFramework';
// 字节流以16进制输出
function uint8ArrayToShowStr(uint8Array) {
return Array.prototype.map
.call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
.join('');
}
function testGenerateAesKey() {
// 创建对称密钥生成器
let symKeyGenerator = cryptoFramework.createSymKeyGenerator("SM4_128");
// 通过密钥生成器随机生成对称密钥
let promiseSymKey = symKeyGenerator.generateSymKey();
promiseSymKey.then( key => {
// 获取对称密钥的二进制数据,输出长度为256bit的字节流
let encodedKey = key.getEncoded();
console.info('key hex:' + uint8ArrayToShowStr(encodedKey.data));
})
}
```
### 根据SM2密钥二进制数据,生成密钥对
> **说明:**
>
> 从API version 10开始, 支持SM2密钥转换。
示例8:根据指定的SM2非对称密钥二进制数据,生成KeyPair对象(场景2、3)
1. 获取SM2二进制密钥数据,封装成DataBlob对象。
2. 调用convertKey方法,传入公钥二进制和私钥二进制(二者非必选项,可只传入其中一个),转换为KeyPair对象。
```js
import cryptoFramework from '@ohos.security.cryptoFramework';
function convertSM2AsyKey() {
let pubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,129,28,207,85,1,130,45,3,66,0,4,90,3,58,157,190,248,76,7,132,200,151,208,112,230,96,140,90,238,211,155,128,109,248,40,83,214,78,42,104,106,55,148,249,35,61,32,221,135,143,100,45,97,194,176,52,73,136,174,40,70,70,34,103,103,161,99,27,187,13,187,109,244,13,7]);
let priKeyArray = new Uint8Array([48,49,2,1,1,4,32,54,41,239,240,63,188,134,113,31,102,149,203,245,89,15,15,47,202,170,60,38,154,28,169,189,100,251,76,112,223,156,159,160,10,6,8,42,129,28,207,85,1,130,45]);
let pubKeyBlob = { data: pubKeyArray };
let priKeyBlob = { data: priKeyArray };
let generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
generator.convertKey(pubKeyBlob, priKeyBlob, (error, data) => {
if (error) {
AlertDialog.show({message : "Convert keypair fail"});
}
AlertDialog.show({message : "Convert KeyPair success"});
})
}
```
## 非对称密钥对象根据参数生成与获取参数
### 场景说明
......@@ -884,7 +983,7 @@ function stringToUint8Array(str) {
}
// 以Promise方式加密
function encryptMessageProMise() {
function encryptMessagePromise() {
// 生成非对称密钥生成器
let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
// 生成加解密生成器
......@@ -927,7 +1026,7 @@ function encryptMessageCallback() {
}
// 以Promise方式加解密
function decryptMessageProMise() {
function decryptMessagePromise() {
// 生成非对称密钥生成器
let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
// 生成加解密生成器,用于加密
......@@ -1211,6 +1310,228 @@ function rsaUseSpecDecryptOAEPPromise() {
}
```
### SM2加解密开发步骤
> **说明:**
>
> 从API version 10开始, 支持SM2加解密。
示例7:使用SM2非对称密钥的加解密操作
1. 生成SM2密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成SM2非对称密钥。
2. 生成Cipher对象。通过createCipher接口创建Cipher对象,执行初始化操作,设置密钥及加解密模式。
3. 执行加解密操作。通过调用Cipher对象提供的doFinal接口,执行加密操作生成密文或执行解密操作生成明文。
```js
import cryptoFramework from "@ohos.security.cryptoFramework"
let plan = "This is cipher test.";
// 可理解的字符串转成字节流
function stringToUint8Array(str) {
let arr = [];
for (let i = 0, j = str.length; i < j; ++i) {
arr.push(str.charCodeAt(i));
}
return new Uint8Array(arr);
}
// 以Promise方式加密
function encryptMessagePromise() {
// 生成非对称密钥生成器
let sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
// 生成加解密生成器
let cipher = cryptoFramework.createCipher("SM2_256|SM3");
// 通过非对称秘钥生成器生成非对称密钥对
let keyGenPromise = sm2Generator.generateKeyPair();
keyGenPromise.then(sm2KeyPair => {
let pubKey = sm2KeyPair.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 sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
// 生成加解密生成器
let cipher = cryptoFramework.createCipher("SM2_256|SM3");
// 通过非对称秘钥生成器生成非对称密钥对
sm2Generator.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("SM2_256");
// 生成加解密生成器,用于加密
let cipher = cryptoFramework.createCipher("SM2_256|SM3");
// 生成加解密生成器,用于解密
let decoder = cryptoFramework.createCipher("SM2_256|SM3");
// 通过非对称秘钥生成器生成非对称密钥对
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;
}
AlertDialog.show({message : "decrypt fail"});
});
}
// 以Callback方式加解密
function decryptMessageCallback() {
// 生成非对称密钥生成器
let rsaGenerator = cryptoFramework.createAsyKeyGenerator("SM2_256");
// 生成加解密生成器,用于加密
let cipher = cryptoFramework.createCipher("SM2_256|SM3");
// 生成加解密生成器,用于解密
let decoder = cryptoFramework.createCipher("SM2_256|SM3");
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;
}
AlertDialog.show({ message : "decrype fail"} );
});
});
});
});
});
}
```
### SM4 ECB以callback方式加解密开发步骤:
> **说明:**
>
> 从API version 10开始, 支持SM4加解密。
示例8:使用SM4对称密钥的加解密操作
1. 创建对称密钥生成器。
2. 通过已有二进制数据生成密钥。
3. 创建加解密生成器。
4. 通过加解密生成器加密或解密数据。
```js
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);
}
// 字节流转成可理解的字符串
function uint8ArrayToString(array) {
let arrayString = '';
for (let i = 0; i < array.length; i++) {
arrayString += String.fromCharCode(array[i]);
}
return arrayString;
}
// SM4 ECB模式示例,callback写法
function testSM4Ecb() {
// 生成非对称密钥生成器
let rsaGenerator = cryptoFramework.createSymKeyGenerator('SM4_128');
// 生成加解密生成器,用于加密
let cipher = cryptoFramework.createCipher("SM4_128|ECB|PKCS7");
// 生成加解密生成器,用于解密
let decoder = cryptoFramework.createCipher("SM4_128|ECB|PKCS7");
let plainText = "this is cipher text";
let input = {data : stringToUint8Array(plainText) };
let cipherData;
let key;
// 通过非对称秘钥生成器生成非对称密钥对
rsaGenerator.generateSymKey(function (err, newKey) {
key = newKey;
// 初始化加解密操作环境:使用公钥开始加密
cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, key, 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, key, null, function (err, data) {
// 解密doFinal
decoder.doFinal(cipherData, function (err, data) {
// 验证解密后,数据与原先数据是否保持一致
if (input.data.toString() === data.data.toString()) {
AlertDialog.show({ message : "decrype success"} );
return;
}
AlertDialog.show({ message : "decrype fail"} );
});
});
});
});
});
}
```
## 使用签名验签操作
### 场景说明
......@@ -1219,6 +1540,7 @@ function rsaUseSpecDecryptOAEPPromise() {
1. 使用RSA签名验签操作
2. 使用ECC签名验签操作
3. 使用RSA签名验签,PSS模式时,获取、设置SignSpecItem参数。
4. 使用SM2签名验签操作
> **说明:**
>
......@@ -1600,6 +1922,67 @@ function verifyMessageCallbackPSS() {
}
```
### SM2签名验签开发步骤
> **说明:**
>
> 从API version 10开始, 支持SM2签名验签。
示例5:使用SM2操作
1. 生成SM2密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成SM2非对称密钥。
2. 生成Sign对象。通过createSign接口创建Sign对象,执行初始化操作并设置签名私钥。
3. 执行签名操作。通过Sign类提供的update接口,添加签名数据,并调用doFinal接口生成数据的签名。
4. 生成Verify对象。通过createVerify接口创建Verify对象,执行初始化操作并设置验签公钥。
5. 执行验签操作。通过Verify类提供的update接口,添加签名数据,并调用doFinal接口传入签名进行验签。
```js
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";
let plan2 = "This is Sign test plan2";
let input1 = { data: stringToUint8Array(plan1) };
let input2 = { data: stringToUint8Array(plan2) };
function signAndVerify() {
let rsaGenerator = cryptoFramework.createAsyKeyGenerator("SM2_256");
let signer = cryptoFramework.createSign("SM2_256|SM3");
rsaGenerator.generateKeyPair(function (err, keyPair) {
globalKeyPair = keyPair;
let priKey = globalKeyPair.priKey;
signer.init(priKey, function (err, data) {
signer.update(input1, function (err, data) {
signer.sign(input2, function (err, data) {
SignMessageBlob = data;
console.info("sign output is " + SignMessageBlob.data);
let verifyer = cryptoFramework.createVerify("SM2_256|SM3");
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);
AlertDialog.show({message:"decrype success"})
});
});
})
});
});
});
});
}
```
## 使用密钥协商操作
### 场景说明
......
......@@ -23,6 +23,10 @@
3DES,也称为 3DESede 或 TripleDES,是三重数据加密算法,相当于是对每个数据块应用三次DES的对称加密算法,它使用3个64位的密钥对数据块进行三次加密。相比DES,3DES因密钥长度变长,安全性有所提高,但其处理速度不高。因此又出现了AES加密算法,AES较于3DES速度更快、安全性更高。
- **SM4密钥**
SM4密码算法是一个分组算法,该算法的分组长度为128位,密钥的长度为128位。加密算法与密钥扩展算法都采用32轮非线性迭代结构,数据解密和数据加密的算法结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。
### 非对称密钥
非对称密钥使用公钥和私钥两个密钥来进行算法操作,公钥对外公开,私钥对外保密。对于加解密操作,一般使用公钥对明文进行加密形成密文,持有私钥的人即可对密文解密形成明文。对于签名验签操作,使用私钥对明文进行签名,公钥持有者可以通过公钥对签名数据做验签,验证数据是否被篡改。
......@@ -77,6 +81,26 @@
pk:公钥,pk = (g ^ sk) mod p。
- **SM2密钥**
SM2算法是一种基于椭圆曲线的公钥密码算法,其密钥长度为256位。SM2算法采用的是Fp域上的椭圆曲线。
Fp域下的SM2密钥参数,包括:
p: 大于3的素数,用于确定Fp。
a, b: 定义椭圆曲线的方程。
g: 椭圆曲线的一个基点(base point),可由gx,gy表示。
n: 基点g的阶(order)。
h: 余因子(cofactor)。
sk: 私钥,是一个随机整数,小于n。
pk: 公钥,是椭圆曲线上的一个点, pk = sk * g。
### 加解密
- **对称AES加解密**
......@@ -105,9 +129,22 @@
> ECB、CBC加密模式,明文长度不是64位整数倍,必须使用填充方法补足。<br/>
> 由于需要填充至分组大小,所以实际算法库中的PKCS5和PKCS7都是以分组大小作为填充长度的,即3DES加密填充至8字节。
- **对称SM4加解密**
算法库目前提供了SM4加解密常用的6种加密模式:ECB、CBC、CTR、OFB、CFB和CFB128。SM4为分组加密算法,分组长度大小为128位。实际应用中明文最后一组可能不足128位,不足数据可以使用各种padding模式做数据填充。下文中描述了各个padding的区别:
- NoPadding:不带填充。
- PKCS5:填充字符由一个字节序列组成,每个字节填充该填充字节序列的长度,规定是8字节填充。
- PKCS7:填充字符和PKCS5填充方法一致,但是可以在1-255字节之间任意填充。
> **说明:**
>
> ECB、CBC加密模式,明文长度不是128位整数倍,必须使用填充方法补足。<br/>
> 由于需要填充至分组大小,所以实际算法库中的PKCS5和PKCS7都是以分组大小作为填充长度的,即SM4加密填充至16字节。
- **非对称RSA加解密**
RSA为加密算法,加密长度需要在固定长度进行,实际应用中会使用各种padding模式做数据填充。算法库目前提供了RSA加解密常用的三种模式:NoPadding、PKCS1和PKCS1_OAEP。下文中描述了各个padding的区别:
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的相关参数。<br><br>
......@@ -121,6 +158,10 @@
>
> RSA钥模 = (RSA的bits + 7) / 8
- **非对称SM2加解密**
SM2为非对称加密算法,是国家密码管理局发布的椭圆曲线公钥密码算法,加密长度在固定长度进行。算法库目前支持以C1C3C2格式输出加密数据,支持对C1C3C2格式的输入数据进行解密。
### 签名验签
- **RSA签名验签**
......@@ -147,6 +188,11 @@
数字签名算法(DSA)的安全性基于整数有限域离散对数问题的困难性,这类签名标准具有较大的兼容性和适用性。
- **SM2**
数字签名算法(SM2)是基于椭圆曲线的算法,由国家密码管理局发布。
### 密钥协商
- **ECDH**
......@@ -155,17 +201,13 @@
### 摘要
消息摘要MD算法是一种能将任意长度的输入消息,通过哈希算法生成长度固定的摘要的算法。消息摘要算法通过其不可逆的特性能被用于敏感信息的加密。消息摘要算法也被称为哈希算法或单向散列算法。
消息摘要算法是一种能将任意长度的输入消息,通过哈希算法生成长度固定的摘要的算法。消息摘要算法通过其不可逆的特性能被用于敏感信息的加密。消息摘要算法也被称为哈希算法或单向散列算法。
在摘要算法相同时,生成的摘要值主要有下列特点:
- 当输入消息相同时,生成摘要序列相同。
- 当输入消息的长度不一致时,生成摘要序列长度固定(摘要长度由算法决定)。
- 当输入消息不一致时,生成摘要序列几乎不会相同(依然存在相同概率,由摘要长度决定相同概率)。
消息摘要算法主要分为三类:MD,SHA与MAC(详见HMAC章节)。
MD算法包括MD2,MD4和MD5。
SHA算法主要包括SHA1,SHA224,SHA256,SHA384,SHA512。
### 消息验证码
HMAC(Hash-based Message Authentication Code)是一种基于密钥的消息认证码算法。HMAC通过指定摘要算法,以通信双方共享密钥与消息作为输入,生成消息认证码用于检验传递报文的完整性,HMAC生成的消息认证码为固定长度。HMAC在消息摘要算法的基础上增加了密钥的输入,确保了信息的正确性。
......@@ -350,6 +392,39 @@ HMAC(Hash-based Message Authentication Code)是一种基于密钥的消息
> 1. DSA不支持通过指定私钥参数(p, q, g, sk)来生成私钥。
> 2. 当使用公共参数(p, q, g)来生成DSA密钥对时,DSA密钥长度至少需要1024位。
### SM2密钥生成规格
> **说明:**
>
> 从API version 10开始, 支持SM2密钥随机生成。
- 支持以字符串参数来生成SM2密钥,其生成参数如下表所示:
|非对称密钥算法|密钥长度(bit)|字符串参数|
|---|---|---|
|SM2|256|SM2_256|
> **说明:**
>
> “字符串参数”是“非对称密钥算法”和“密钥长度”使用连接符号“_”拼接而成,用于在创建非对称密钥生成器时,指定密钥规格。
### SM4密钥生成规格
> **说明:**
>
> 从API version 10开始, 支持SM4密钥随机生成。
- 支持以字符串参数来生成SM4密钥,其生成参数如下表所示:
|对称密钥算法|密钥长度(bit)|字符串参数|
|---|---|---|
|SM4|128|SM4_128|
> **说明:**
>
> “字符串参数”是“对称密钥算法”和“密钥长度”使用连接符号“_”拼接而成,用于在创建对称密钥生成器时,指定密钥规格。
## 加解密规格
### 对称加解密
......@@ -372,11 +447,18 @@ HMAC(Hash-based Message Authentication Code)是一种基于密钥的消息
|AES|CFB|AES[128\|192\|256]\|CFB\|[NoPadding\|PKCS5\|PKCS7]|
|AES|GCM|AES[128\|192\|256]\|GCM\|[NoPadding\|PKCS5\|PKCS7]|
|AES|CCM|AES[128\|192\|256]\|CCM\|[NoPadding\|PKCS5\|PKCS7]|
|SM4|ECB|SM4_128\|ECB\|[NoPadding\|PKCS5\|PKCS7]|
|SM4|CBC|SM4_128\|CBC\|[NoPadding\|PKCS5\|PKCS7]|
|SM4|CTR|SM4_128\|CTR\|[NoPadding\|PKCS5\|PKCS7]|
|SM4|OFB|SM4_128\|OFB\|[NoPadding\|PKCS5\|PKCS7]|
|SM4|CFB|SM4_128\|CFB\|[NoPadding\|PKCS5\|PKCS7]|
|SM4|CFB128|SM4_128\|CFB128\|[NoPadding\|PKCS5\|PKCS7]|
> **说明:**
>
> 1. []中只能任选一项。
> 2. “字符串参数”是“对称加解密算法(含密钥长度)”、“分组模式”、“填充模式”拼接而成,用于在创建对称加解密实例时,指定对称加解密算法规格。
> 3. “字符串参数”中“SM4<sup>10+</sup>”和密钥长度间需要添加下划线
### 非对称RSA加解密
......@@ -488,6 +570,25 @@ RSA加解密时,涉及三种填充模式:NoPadding, PKCS1和PKCS1_OAEP。
>
> 上表说明了算法库对于OAEP参数的获取和设置支持情况,打√的表示需要对该参数具有获取或设置的能力。
### 非对称SM2加解密
> **说明:**
>
> 从API version 10开始, 支持非对称SM2加解密,支持不带密钥长度的规格。
SM2加解密时,仅支持C1C3C2密文排列组合模式。SM2非对称加密的结果由C1,C2,C3三部分组成。其中C1是根据生成的随机数计算出的椭圆曲线点,C2是密文数据,C3是通过指定摘要算法计算的值。国密新标准以C1,C3,C2顺序存放,不支持无摘要加密。
- 支持的加密算法:
| 非对称密钥类型 | 摘要 | 字符串参数 |
|---|---|---|
|SM2_256|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512\|SM3]|SM2_256\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512\|SM3]|
|SM2|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512\|SM3]|SM2_256\|[MD5\|SHA1\|SHA224\|SHA256\|SHA384\|SHA512\|SM3]|
> **说明:**
>
> “字符串参数”是“非对称密钥类型”、“填充模式”拼接而成,用于在创建非对称加解密实例时,指定非对称加解密算法规格。
## 签名验签规格
### RSA签名验签
......@@ -628,6 +729,26 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。
> 例如:"DSA1024|SHA256"
> 3. 在上表最后一行,为了兼容由密钥参数生成的密钥,DSA签名验签参数输入密钥类型时支持不带长度,签名验签运算取决于实际输入的密钥长度。
### SM2签名验签
> **说明:**
>
> 从API version 10开始, 支持SM2签名验签。
- 支持的SM2参数:
|非对称密钥类型|摘要|字符串参数|
|---|---|---|
|SM2_256|SM3|SM2_256\|SM3|
|SM2|SM3|SM2\|SM3|
> **说明:**
>
> 1. []内的参数只能任选一项,非[]内的为固定值。
> 2. 使用时请从表格中选择非对称密钥类型、摘要二个数据,用|拼接成“字符串参数”,用于在创建非对称签名验签实例时,指定非对称签名验签算法规格。<br>
> SM2签名时只支持SM3摘要。
## 密钥协商规格
### ECDH
......@@ -656,6 +777,10 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。
- 加解密算法库框架当前支持的MD算法参数:
> **说明:**
>
> 从API version 10开始, 支持SM3。
|摘要算法|支持种类|
|---|---|
|HASH|SHA1|
......@@ -664,6 +789,7 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。
|HASH|SHA384|
|HASH|SHA512|
|HASH|MD5|
|HASH|SM3|
> **说明:**
>
......@@ -673,6 +799,10 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。
- 加解密算法库框架当前支持的HMAC算法参数:
> **说明:**
>
> 从API version 10开始, 支持SM3。
|摘要算法|支持种类|
|---|---|
|HASH|SHA1|
......@@ -680,6 +810,7 @@ RSA签名验签时,涉及两种填充模式:PKCS1和PSS。
|HASH|SHA256|
|HASH|SHA384|
|HASH|SHA512|
|HASH|SM3|
> **说明:**
>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册