从API版本26.0.0开始,支持ECIES算法,ECIES是一种基于椭圆曲线密码学的加密算法。
约束条件:
调用cryptoFramework.createAsyKeyGenerator和AsyKeyGenerator.generateKeyPair,使用ECC算法生成密钥对。
调用cryptoFramework.createKeyAgreement和KeyAgreement.generateSecret,基于本端的私钥(KeyPair.priKey)与对端的公钥(KeyPair.pubKey)进行密钥协商,返回共享密钥。
X963KDF密钥派生,调用cryptoFramework.createKdf和Kdf.generateSecret,基于协商的共享密钥(Secret)进行密钥派生,返回派生后的密钥。
调用cryptoFramework.createCipher,指定字符串参数'AES128|GCM',创建对称密钥类型为AES128、分组模式为GCM的Cipher实例,用于完成加密操作。
调用Cipher.init,设置模式为加密(cryptoFramework.CryptoMode.ENCRYPT_MODE),指定加密密钥(SymKey)和GCM模式对应的加密参数(GcmParamsSpec),初始化加密Cipher实例。
调用Cipher.update,更新数据(明文)。
调用Cipher.doFinal,获取加密后的数据。
读取GcmParamsSpec.authTag作为解密的认证信息。
调用cryptoFramework.createAsyKeyGenerator和AsyKeyGenerator.generateKeyPair,使用ECC算法生成密钥对。
调用cryptoFramework.createKeyAgreement和KeyAgreement.generateSecret,基于本端的私钥(KeyPair.priKey)与对端的公钥(KeyPair.pubKey)进行密钥协商,返回共享密钥。
X963KDF密钥派生,调用cryptoFramework.createKdf和Kdf.generateSecret,基于协商的共享密钥(Secret)进行密钥派生,返回派生后的密钥。
调用cryptoFramework.createCipher,指定字符串参数'AES128|GCM',创建对称密钥类型为AES128、分组模式为GCM的Cipher实例,用于完成解密操作。
调用Cipher.init,设置模式为解密(cryptoFramework.CryptoMode.DECRYPT_MODE),指定解密密钥(SymKey)和GCM模式对应的解密参数(GcmParamsSpec),初始化解密Cipher实例。
调用Cipher.update,更新数据(密文)。
调用Cipher.doFinal,获取解密后的数据。
异步方法示例:
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
namespace ECIES {
function generateGcmParamsSpec(ivData: Uint8Array): cryptoFramework.GcmParamsSpec {
let ivBlob: cryptoFramework.DataBlob = {
data: ivData,
};
let rand: cryptoFramework.Random = cryptoFramework.createRandom();
let aadBlob: cryptoFramework.DataBlob = rand.generateRandomSync(8);
let tagBlob: cryptoFramework.DataBlob = rand.generateRandomSync(16);
// GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中
let gcmParams: cryptoFramework.GcmParamsSpec = {
iv: ivBlob,
aad: aadBlob,
authTag: tagBlob,
algName: 'GcmParamsSpec',
};
return gcmParams;
}
async function generateSecret(priKey: cryptoFramework.PriKey, pubKey: cryptoFramework.PubKey):
Promise<cryptoFramework.DataBlob> {
// EC密钥协商
let agreement: cryptoFramework.KeyAgreement = cryptoFramework.createKeyAgreement('ECC256');
let keyData: cryptoFramework.DataBlob = await agreement.generateSecret(priKey, pubKey);
let infoData: Uint8Array = new Uint8Array(buffer.from('infostring', 'utf-8').buffer);
let spec: cryptoFramework.X963KdfSpec = {
algName: 'X963KDF',
key: keyData.data,
info: infoData,
keySize: 32, // 前16字节作为AES128的IV,后16字节作为密钥
};
// 使用X963KDF进行密钥派生
let kdf = cryptoFramework.createKdf('X963KDF|SHA256');
let secret = await kdf.generateSecret(spec);
return secret;
}
async function generateSymKey(secret: cryptoFramework.DataBlob): Promise<cryptoFramework.SymKey> {
let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES128');
let keyData: cryptoFramework.DataBlob = {
data: secret.data.slice(16),
};
let symKey: cryptoFramework.SymKey = await symKeyGenerator.convertKey(keyData);
return symKey;
}
async function encrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
plainText: cryptoFramework.DataBlob): Promise<cryptoFramework.DataBlob> {
// AES-GCM对称加密
let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams);
let cipherText: cryptoFramework.DataBlob = await cipher.update(plainText);
gcmParams.authTag = await cipher.doFinal(null);
return cipherText;
}
async function decrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
cipherText: cryptoFramework.DataBlob): Promise<cryptoFramework.DataBlob> {
// AES-GCM对称解密
let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams);
let plainText: cryptoFramework.DataBlob = await cipher.doFinal(cipherText);
return plainText;
}
export async function doEciesTest(): Promise<string> {
try {
// 生成A端和B端的EC密钥对
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('ECC256');
let keyPairA: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
let keyPairB: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
// A端加密:A端的私钥 + B端的公钥
let secretA: cryptoFramework.DataBlob = await generateSecret(keyPairA.priKey, keyPairB.pubKey);
let symKeyA: cryptoFramework.SymKey = await generateSymKey(secretA);
let ivData: Uint8Array = secretA.data.slice(0, 16);
let gcmParams: cryptoFramework.GcmParamsSpec = generateGcmParamsSpec(ivData);
let message: string = 'This is a test message!!!';
let plainText: cryptoFramework.DataBlob = {
data: new Uint8Array(buffer.from(message, 'utf-8').buffer),
};
let cipherData: cryptoFramework.DataBlob = await encrypt(symKeyA, gcmParams, plainText);
// B端解密:B端的私钥 + A端的公钥
let secretB: cryptoFramework.DataBlob = await generateSecret(keyPairB.priKey, keyPairA.pubKey);
let symKeyB: cryptoFramework.SymKey = await generateSymKey(secretB);
let plainData: cryptoFramework.DataBlob = await decrypt(symKeyB, gcmParams, cipherData);
console.info('doEciesTest success, message: ' + buffer.from(plainData.data).toString('utf-8'));
return 'Success';
} catch (error) {
let e: BusinessError = error as BusinessError;
console.error(`doEciesTest failed: errCode: ${e.code}, message: ${e.message}`);
return 'Failed';
}
}
} 同步方法示例:
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
namespace ECIES {
function generateGcmParamsSpec(ivData: Uint8Array): cryptoFramework.GcmParamsSpec {
let ivBlob: cryptoFramework.DataBlob = {
data: ivData,
};
let rand: cryptoFramework.Random = cryptoFramework.createRandom();
let aadBlob: cryptoFramework.DataBlob = rand.generateRandomSync(8);
let tagBlob: cryptoFramework.DataBlob = rand.generateRandomSync(16);
// GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中
let gcmParams: cryptoFramework.GcmParamsSpec = {
iv: ivBlob,
aad: aadBlob,
authTag: tagBlob,
algName: 'GcmParamsSpec',
};
return gcmParams;
}
function generateSecret(priKey: cryptoFramework.PriKey, pubKey: cryptoFramework.PubKey):
cryptoFramework.DataBlob {
// EC密钥协商
let agreement: cryptoFramework.KeyAgreement = cryptoFramework.createKeyAgreement('ECC256');
let keyData: cryptoFramework.DataBlob = agreement.generateSecretSync(priKey, pubKey);
let infoData: Uint8Array = new Uint8Array(buffer.from('infostring', 'utf-8').buffer);
let spec: cryptoFramework.X963KdfSpec = {
algName: 'X963KDF',
key: keyData.data,
info: infoData,
keySize: 32, // 前16字节作为AES128的IV,后16字节作为密钥
};
// 使用X963KDF进行密钥派生
let kdf = cryptoFramework.createKdf('X963KDF|SHA256');
let secret = kdf.generateSecretSync(spec);
return secret;
}
function generateSymKey(secret: cryptoFramework.DataBlob): cryptoFramework.SymKey {
let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES128');
let keyData: cryptoFramework.DataBlob = {
data: secret.data.slice(16),
};
let symKey: cryptoFramework.SymKey = symKeyGenerator.convertKeySync(keyData);
return symKey;
}
function encrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
plainText: cryptoFramework.DataBlob): cryptoFramework.DataBlob {
// AES-GCM对称加密
let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams);
let cipherText: cryptoFramework.DataBlob = cipher.updateSync(plainText);
gcmParams.authTag = cipher.doFinalSync(null);
return cipherText;
}
function decrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
cipherText: cryptoFramework.DataBlob): cryptoFramework.DataBlob {
// AES-GCM对称解密
let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
cipher.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams);
let plainText: cryptoFramework.DataBlob = cipher.doFinalSync(cipherText);
return plainText;
}
export function doEciesTest(): string {
try {
// 生成A端和B端的EC密钥对
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('ECC256');
let keyPairA: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
let keyPairB: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
// A端加密:A端的私钥 + B端的公钥
let secretA: cryptoFramework.DataBlob = generateSecret(keyPairA.priKey, keyPairB.pubKey);
let symKeyA: cryptoFramework.SymKey = generateSymKey(secretA);
let ivData: Uint8Array = secretA.data.slice(0, 16);
let gcmParams: cryptoFramework.GcmParamsSpec = generateGcmParamsSpec(ivData);
let message: string = 'This is a test message!!!';
let plainText: cryptoFramework.DataBlob = {
data: new Uint8Array(buffer.from(message, 'utf-8').buffer),
};
let cipherData: cryptoFramework.DataBlob = encrypt(symKeyA, gcmParams, plainText);
// B端解密:B端的私钥 + A端的公钥
let secretB: cryptoFramework.DataBlob = generateSecret(keyPairB.priKey, keyPairA.pubKey);
let symKeyB: cryptoFramework.SymKey = generateSymKey(secretB);
let plainData: cryptoFramework.DataBlob = decrypt(symKeyB, gcmParams, cipherData);
console.info('doEciesTest success, message: ' + buffer.from(plainData.data).toString('utf-8'));
return 'Success';
} catch (error) {
let e: BusinessError = error as BusinessError;
console.error(`doEciesTest failed: errCode: ${e.code}, message: ${e.message}`);
return 'Failed';
}
}
}