@amazon-devices/keplercrypto
KeplerCrypto API提供的功能可让您使用行业标准算法执行典型的加密操作,例如读取、生成和管理加密密钥。
注意: 不支持在模拟器中运行此API。
开始使用
设置
- 将以下库依赖项添加到package.json文件的
dependencies部分。
"@amazon-devices/keplercrypto": " ~2.0,
用法
在使用KeplerCrypto功能的源文件中,从Turbo模块导入所需的数据类型。
import {
AsymmetricAlgorithm,
AsymmetricKeyBuilder,
CbcContextBuilder,
CtrContextBuilder,
Crypto,
DigestAlgorithm,
EccCurve,
GcmContextBuilder,
KeyPurpose,
PrivateKey,
PublicKey,
SymmetricAlgorithm,
SymmetricKey,
} from '@amazon-devices/keplercrypto';
要想使用KeplerCrypto Turbo模块,首先必须创建Crypto类的实例。
/**
* 创建Crypto对象。
*/
const crypto = new Crypto();
下面的示例代码仅用于解释说明,为了便于理解,已做了简化处理。当发生错误时,KeplerCrypto API中的大多数方法都会抛出一个异常。
将您的调用封装在try-catch块中,以恰当地处理发生的任何错误。
try {
crypto.getRandom(length);
} catch (e) {
if (e instanceof InvalidArgumentError) {...}
else if (e instanceof SecurityError) {...}
}
查看文档,了解各个特定方法可能抛出的具体异常。
ECDSA签名和验证
以下示例代码包括ECDSA密钥对生成、消息签名和验证。
步骤1: 创建ECDSA密钥构建器
// 创建新的ECDSA密钥构建器
const keyBuilder = crypto.makeEccKeyBuilder();
// 将密钥标记为可导出
keyBuilder.exportable = true;
// 设置密钥用途
keyBuilder.purposes = [KeyPurpose.SIGN, KeyPurpose.VERIFY];
步骤2: 生成密钥对
您可以生成ECDSA密钥对或构造私钥。
要生成ECDSA密钥对,请调用buildGenerated()。
// 生成ECDSA密钥对
const privateKey = await keyBuilder.buildGenerated();
// 获取公钥
const publicKey = privateKey.getPublicKey();
要根据现有DER字符串构造私钥,请调用buildPrivateFromDer()。
// 根据现有DER字符串构建私钥
const privateKey = await keyBuilder.buildPrivateFromDer(privateKeyDer);
const publicKey = privateKey.getPublicKey();
</viv>
步骤3: 创建签名上下文构建器
const builder = crypto.makeSignatureContextBuilder();
builder.signingAlgorithm = crypto.getAsymmetricAlgorithmByName(AsymmetricAlgorithm.ECDSA);
步骤4: 对消息进行签名并获取签名
// 使用私钥构建签名上下文
const signer = builder.buildSigningContext(privateKey);
const message = '这是一条非常重要的消息';
const messageBuffer = new TextEncoder().encode(message).buffer;
// 对消息签名
const signedMessage = await signer.sign(messageBuffer);
步骤5: 使用签名验证消息
// 使用公钥构建验证上下文
const verifier = builder.buildVerificationContext(publicKey);
// 验证消息
const result = await verifier.verify(messageBuffer, signedMessage);
RSA签名和验证
以下示例代码包括RSA密钥对生成、消息签名和验证。
步骤1: 创建RSA密钥构建器
// 创建RSA密钥构建器
const keybuilder = crypto.makeRsaKeyBuilder();
// 将密钥标记为可导出
keyBuilder.exportable = true;
// 设置密钥用途
keyBuilder.purposes = [KeyPurpose.SIGN, KeyPurpose.VERIFY];
步骤2: 生成密钥对
您可以生成RSA密钥对或构造私钥。
要生成RSA密钥对,请调用buildGenerated()。
// 生成RSA密钥对
const privateKey = await keyBuilder.buildGenerated();
// 获取公钥
const publicKey = privateKey.getPublicKey();
要根据现有DER字符串构造私钥,请调用buildPrivateFromDer()。
// 根据现有DER字符串构建私钥
const privateKey = await keyBuilder.buildPrivateFromDer(privateKeyDer);
const publicKey = privateKey.getPublicKey();
步骤3: 创建签名上下文构建器并对消息进行签名
通过调用buildSigningContext() 创建签名上下文构建器,然后使用RSA-PKCS1 v1.5架构对消息进行签名以获取签名。
// 使用私钥构建签名上下文
const builder = crypto.makeRsassaPkcs1ContextBuilder();
const digestAlgorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
builder.digestAlgorithm = digestAlgorithm;
const rsaPkcs1Signer = builder.buildSigningContext(privateKey);
const message = '这是一条非常重要的消息';
const messageBuffer = new TextEncoder().encode(message).buffer;
// 对消息签名
const signedMessage = await rsaPkcs1Signer.sign(messageBuffer);
步骤4: 验证消息
通过调用使用RSA-PKCS1 v1.5标准的rsaPkcs1Verifier.verify() 来使用签名进行消息验证。
// 使用公钥构建验证上下文
const rsaPkcs1Verifier = builder.buildVerificationContext(publicKey);
// 验证消息
const result = await rsaPkcs1Verifier.verify(messageBuffer, signedMessage);
步骤5: 对消息签名并获得签名
要使用RSA-PSS标准对消息进行签名,请调用rsaPssSigner.sign(),它会返回已签名消息的签名。
// 为了保证填充机制正确并提升安全性,盐值的长度通常应与摘要长度保持一致。
// 使用不同的盐值长度可能也能工作,但不建议这样做。
builder.saltLength = digestAlgorithm.size / 8;
// 使用私钥构建签名上下文
const rsaPssSigner = builder.buildSigningContext(privateKey);
const message = '这是一条非常重要的消息';
const messageBuffer = new TextEncoder().encode(message).buffer;
// 对消息签名
const signedMessage = await rsaPssSigner.sign(messageBuffer);
要验证消息,请调用rsaPssVerifier.verify() 并传递消息的签名。
// 使用公钥构建验证上下文
const rsaPssVerifier = builder.buildVerificationContext(publicKey);
// 验证消息
const result = await rsaPssVerifier.verify(messageBuffer, signedMessage);
HMAC签名和验证
以下示例说明如何生成密钥、导出密钥、对数据签名并进行验证。
// 生成密钥
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
keyBuilder.bits = 256;
const key = await keyBuilder.buildGenerated();
// 导出安全密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 获取摘要算法
const digestAlgorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
// 使用安全密钥和摘要算法创建HMAC上下文构建器
const builder = crypto.makeHmacContextBuilder();
builder.key = key;
builder.digestAlgorithm = digestAlgorithm;
// 对数据签名
const signContext = builder.build();
const tag = await signContext.sign(plaintext);
// 验证数据
const verifyContext = builder.build();
const tag = signContext.sign(plaintext);
const result1 = await verifyContext.verify(plaintext, tag);
// 尝试使用导出的密钥进行验证
const exportedBuilder = crypto.makeHmacContextBuilder();
exportedBuilder.key = exportedKey;
exportedBuilder.digestAlgorithm(digestAlgorithm);
const exportedVerifyContext = exportedBuilder.build();
const result2 = await exportedVerifyContext.verify(plaintext, tag);
使用AES CBC分组密码对消息进行加密
以下示例说明如何生成AES-256密钥、导出密钥、创建AES-256 CBC密码上下文构建器,以及如何使用它对明文进行签名。
// 生成AES-256密钥
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.bits = 256;
keyBuilder.exportable = true;
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
keyBuilder.purposes = purposes;
const key = await keyBuilder.buildGenerated();
// 导出AES密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = purposes;
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 创建AES-256 CBC密码上下文构建器
const builder = crypto.makeCbcCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
// 设置正确的IV
const iv = new Uint8Array(builder.ivSize).buffer;
builder.iv = iv;
// 设置密钥
builder.key = key;
// 加密明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const encryptionContext = builder.buildEncryptionContext();
const ciphertext = await encryptionContext.encrypt(plaintextBuffer);
// 将密文解密
const decryptionContext = builder.buildDecryptionContext();
const decrypted = await decryptionContext.decrypt(ciphertext);
// 尝试使用导出的密钥然后用它将密文解密
const exportedBuilder = crypto.makeCbcCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
exportedBuilder.iv = iv;
exportedBuilder.key = exportedKey;
const exportedDecryptionContext = exportedBuilder.buildDecryptionContext();
const exportedDecrypted = await exportedDecryptionContext.decrypt(ciphertext);
使用AES CTR分组密码对消息进行加密
以下示例说明如何生成AES-CTR密钥、导出密钥、创建AES-256 CTR密码上下文构建器,以及如何使用它对明文进行签名。
// 生成AES-256密钥
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = purposes;
keyBuilder.bits = 256;
const key = await keyBuilder.buildGenerated();
// 导出AES密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = purposes;
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 创建AES CTR密码上下文构建器
const builder = crypto.makeCtrCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
// 设置正确的计数和随机数
builder.count = 12;
builder.nonce = 12;
// 设置密钥
builder.key = key;
// 加密明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const encryptionContext = builder.buildEncryptionContext();
const ciphertext = await encryptionContext.encrypt(plaintextBuffer);
// 将密文解密
const decryptionContext = builder.buildDecryptionContext();
const decrypted = await decryptionContext.decrypt(ciphertext);
const result1 = plaintext === new TextDecoder('utf-8').decode(decrypted);
// 将导出的密钥与CTR密码上下文构建器一起使用
builder.key = exportedKey;
// 尝试使用导出的密钥解密
const exportedDecryptionContext = builder.buildDecryptionContext();
const exportedDecrypted = await exportedDecryptionContext.decrypt(ciphertext);
const result2 = plaintext === new TextDecoder('utf-8').decode(exportedDecrypted);
使用AES GCM分组密码对消息进行加密
以下示例说明如何生成AES-256 GCM密钥、导出密钥、创建AES-256 GCM密码上下文构建器,以及如何使用它对明文进行签名。
// 生成AES-256密钥
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = purposes;
keyBuilder.bits = 256;
const key = await keyBuilder.buildGenerated();
// 导出AES密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = purposes;
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 创建AES-256 GCM密码上下文构建器
const builder = crypto.makeGcmCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
// 使用4字节标识符初始化IV以使用随机化的
// 随机数序列。或者,使用大小为builder.getIvSize() 的向量对其进行初始化
// 以使用任意随机数。
const iv = new Uint8Array([0xab, 0xcd, 0xef, 0x01]);
builder.iv = iv;
builder.key = key;
// 加密明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const encryptionContext = builder.buildEncryptionContext();
const ciphertext = await encryptionContext.encrypt(plaintextBuffer);
// 将密文解密
const decryptionContext = builder.buildDecryptionContext();
const decrypted = await decryptionContext.decrypt(ciphertext);
// 将导出的密钥与GCM密码上下文构建器一起使用
builder.key = exportedKey;
// 尝试使用导出的密钥解密
const exportedDecryptionContext = builder.buildDecryptionContext();
const exportedDecrypted = await exportedDecryptionContext.decrypt(ciphertext);
使用RSA-OAEP加密消息
以下示例说明如何生成RSA-OAEP密钥、导出密钥、创建上下文构建器,以及如何使用它对明文进行签名。
// 获取摘要算法和非对称算法,并定义密钥用途
const sha = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA384);
const alg = crypto.getAsymmetricAlgorithmByName(AsymmetricAlgorithm.RSA_OAEP);
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
// 创建一个RsaOaepKeyBuilder
const keyBuilder = crypto.makeRsaOaepKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = purposes;
keyBuilder.bits = 384;
// 从密钥构建器生成私钥
const privateKey = await keyBuilder.buildGenerated();
// 导出密钥供以后的测试案例使用
const rawPrivateKey = await privateKey.exportDer();
// 获取对应的公钥
const publicKey = privateKey.getPublicKey();
// 导出公钥以备后用
const rawPublicKey = await publickey.exportDer();
// 根据消息构建明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
// 使用alg和sha构建RSA-OAEP密码上下文
const rsaOaepCipherContext = crypto.makeRsaOaepCipherContextBuilder(alg, sha);
// 使用公钥基于RSA-OAEP密码上下文构建加密上下文
const rsaOaepEncryptionContext = rsaOaepCipherContext.buildEncryptionContext(publickey);
// 使用加密上下文加密
const ciphertext = await rsaOaepEncryptionContext.encrypt(plaintextBuffer);
// 基于密码上下文构建解密上下文
const rsaOaepDecryptionContext = rsaOaepCipherContext.buildDecryptionContext(privatekey);
// 使用解密上下文进行解密
const decrypted = await rsaOaepDecryptionContext.decrypt(ciphertext);
// 确保解密后的消息与明文相同
const result1 = plaintext === new TextDecoder('utf-8').decode(decrypted);
// 使用导出的密钥来构建私钥和公钥
const exportedPrivkey = await keyBuilder.buildPrivateFromDer(rawPrivateKey);
const exportedRsaOaepDecryptionContext = rsaOaepCipherContext.buildDecryptionContext(exportedPrivkey);
// 使用导入的密钥解密密文并确保解密后的消息与明文一致
const exportedDecrypted = await exportedRsaOaepDecryptionContext.decrypt(ciphertext);
const result2 = plaintext === new TextDecoder('utf-8').decode(exportedDecrypted);
// 使用导入的公钥进行加密,使用原始私钥进行解密
// 并确保解密后的消息与明文一致
const exportedPublicKey = await keyBuilder.buildPublicFromDer(rawPublicKey);
const exportedRsaOaepEncryptionContext = rsaOaepCipherContext.buildEncryptionContext(exportedPublicKey);
const exportedCiphertext = await exportedRsaOaepEncryptionContext.encrypt(plaintextBuffer);
const exportedDecryptedAgain = await rsaOaepDecryptionContext.decrypt(exportedCiphertext);
const result3 = plaintext === new TextDecoder('utf-8').decode(exportedDecryptedAgain);
创建消息摘要
以下代码示例调用getDigestAlgorithmByName() 来获取摘要,创建摘要上下文,对示例字符串进行编码,并获取该字符串的摘要。
const builder = crypto.makeDigestContextBuilder();
builder.digestAlgorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
const digestContext = builder.build();
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const hash = await digestContext.digest(plaintextBuffer);
使用HKDF(HMAC密钥派生函数)派生密钥
const salt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const info = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // 来自密钥的额外信息
// 创建密钥(如果您已经有了一个用于DERIVE的密钥,则为可选项)
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.bits = 256; // 任意长度
keyBuilder.exportable = false;
keyBuilder.purposes = [KeyPurpose.DERIVE]; // 重要须知:密钥必须能够派生
const secret = await keyBuilder.buildGenerated();
const algorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
// 创建上下文构建器
const ctxBuilder = crypto.makeHkdfContextBuilder();
ctxBuilder.info = info;
ctxBuilder.salt = salt;
ctxBuilder.hashAlgorithm = algorithm;
// 创建派生上下文
const ctx = ctxBuilder.buildKeyDerivationContext(secret);
// 派生对称密钥
// 重要须知:派生的密钥必须与所用算法的长度相匹配
const generatedKeyLen = algorithm.size / 8;
const symmKey = ctx.deriveKey(generatedKeyLen);
// 改为派生一个原始密钥
const rawKey = ctx.deriveBits(generatedKeyLen);
使用PBKDF2(基于密码的密钥派生函数2)派生密钥
const iterations = 10000; // 迭代次数,值越大越安全,但性能下降幅度也越大。
// 10000是一个合理的值,不会导致性能下降太多
const salt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const generatedKeyLen = 512;
// 创建上下文构建器
const ctxBuilder = crypto.makePbkdf2ContextBuilder();
// 创建密钥(如果您已经有了一个用于DERIVE的密钥,则为可选项)
const keyBuilder = crypto.makeSymmetricKeyBuilder()
keyBuilder.bits = 256; // 任意长度
keyBuilder.exportable = false;
keyBuilder.purposes = [KeyPurpose.DERIVE]; // 重要须知:密钥必须能够派生
const secret = await keyBuilder.buildGenerated();
const algorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
// 创建派生上下文
ctxBuilder.iterations = iterations;
ctxBuilder.salt = salt;
ctxBuilder.hashAlgorithm = algorithm;
const ctx = buildKeyDerivationContext(secret);
// 派生对称密钥
const symmKey = await ctx.deriveKey(generatedKeyLen);
// 改为派生一个原始密钥
const rawKey = await ctx.deriveBits(generatedKeyLen);
网页加密API shim层
KeplerCrypto库提供了一个shim层,用于实现网页加密API(仅提供英文版)。有关API方法和参数,请参阅现有的网页加密API MDN文档。
网页加密用法示例
以下示例介绍如何导入和使用网页加密API shim层。
导入API
import {WebCrypto} from '@amazon-devices/keplercrypto';
初始化WebCrypto对象
const wc = new WebCrypto();
可选: 在globalThis上公开crypto实例
// 如果globalThis不存在,则定义它
if (typeof globalThis === 'undefined') {
(window as any).globalThis = window;
}
globalThis.crypto = wc.crypto as any;
调用网页加密API
下一个代码示例生成ECDH CryptoKeyPair。
const nonExtractableKeyPair = (await wc.crypto.subtle.generateKey(
{
name: 'ECDH',
namedCurve: 'P-256',
},
false, // 不可提取
['deriveBits'],
)) as CryptoKeyPair;
支持的网页加密算法
该库仍在开发中,网页加密实现仅提供整个W3C网页加密规范的一个子集。未来版本将支持更多操作。
注意:网页加密shim层实现中不支持deriveKey。
有关密钥派生功能,请使用标准KeplerCrypto API,如上文“使用HKDF派生密钥”和“使用PBKDF2派生密钥”的示例所示。
网页加密支持的密钥格式
使用网页加密API导入和导出密钥时,支持以下格式:
| 密钥类型 | 支持的导入格式 | 支持的导出格式 |
|---|---|---|
| AES | raw、jwk | raw、jwk |
| HMAC | raw、jwk | raw、jwk |
| ECDH | pkcs8、spki、jwk | pkcs8、spki、jwk |
格式描述:
- raw: 未格式化的二进制数据,用于对称密钥(AES或HMAC)或椭圆曲线公钥。
- pkcs8: RSA或椭圆曲线私钥的PKCS #8格式。
- spki: RSA或椭圆曲线公钥的SubjectPublicKeyInfo格式。
- jwk: JSON网页密钥格式(所有密钥类型均支持)
导入密钥的示例:
// 导入原始格式的AES密钥
const rawKey = new Uint8Array([...]); // 您的密钥字节
const importedKey = await wc.crypto.subtle.importKey(
"raw", // 格式
rawKey, // 密钥数据
{ name: "AES-GCM" }, // 算法
false, // 可提取
["encrypt", "decrypt"] // 密钥用法
);
网页加密API支持矩阵
算法操作:
- ✓ = 支持
- ✗ = 不支持
| 算法 | encrypt() | decrypt() | sign() | verify() | digest() | deriveKey() | importKey() | exportKey() | deriveBits() | generateKey() |
|---|---|---|---|---|---|---|---|---|---|---|
| RSASSA-PKCS1v1 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
| RSA-PSS | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
| RSA-OAEP | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
| ECDH | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✓ | ✓ |
| ECDSA | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
| AES-CTR | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✗ | ✓ |
| AES-CBC | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✗ | ✓ |
| AES-GCM | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✗ | ✓ |
| HMAC | ✗ | ✗ | ✓ | ✓ | ✗ | ✗ | ✓ | ✓ | ✗ | ✗ |
| SHA-1 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ |
| SHA-256 | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
| SHA-384 | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
| SHA-512 | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
| HKDF | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
| PBKDF2 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
KeplerCrypto概述
KeplerCrypto API提供的功能可让您使用行业标准算法执行典型的加密操作,例如读取、生成和管理加密密钥。
开始使用
KeplerCrypto API已包含在Kepler SDK中。
安装和设置KeplerCrypto
要将API添加到您的项目,请在应用的根目录中打开package.json文件并添加以下依赖项。
"dependencies": {
"@amazon-devices/keplercrypto": "*",
...
},
在您的应用中使用KeplerCrypto API
在使用KeplerCrypto功能的源文件中,从Turbo模块导入所需的数据类型。
import {
AsymmetricAlgorithm,
AsymmetricKeyBuilder,
CbcContextBuilder,
CtrContextBuilder,
Crypto,
DigestAlgorithm,
EccCurve,
GcmContextBuilder,
KeyPurpose,
PrivateKey,
PublicKey,
SymmetricAlgorithm,
SymmetricKey,
} from '@amazon-devices/keplercrypto';
接下来,获取一个Crypto实例。
/**
* 创建Crypto对象。
*/
const crypto = new Crypto();
要想使用KeplerCrypto Turbo模块,首先必须创建Crypto类的实例。
KeplerCrypto常见用例
下面的示例代码仅用于解释说明,为了便于理解,已做了简化处理。当发生错误时,KeplerCrypto API中的大多数方法都会抛出一个异常。
将您的调用封装在try-catch块中,以恰当地处理发生的任何错误。例如:
try {
crypto.getRandom(length);
} catch (e) {
if (e instanceof InvalidArgumentError) {...}
else if (e instanceof SecurityError) {...}
}
查看您调用的任何方法的文档,了解它抛出的特定异常。
注意: 不支持在模拟器中运行此Turbo模块。
ECDSA签名和验证
以下示例代码包括ECDSA密钥对生成、消息签名和验证。
步骤1: 创建ECDSA密钥构建器
// 创建新的ECDSA密钥构建器
const keyBuilder = crypto.makeEccKeyBuilder();
// 将密钥标记为可导出
keyBuilder.exportable = true;
// 设置密钥用途
keyBuilder.purposes = [KeyPurpose.SIGN, KeyPurpose.VERIFY];
步骤2: 生成密钥对
您可以生成ECDSA密钥对或构造私钥。
要生成ECDSA密钥对,请调用buildGenerated()。
// 生成ECDSA密钥对
const privateKey = await keyBuilder.buildGenerated();
// 获取公钥
const publicKey = privateKey.getPublicKey();
要根据现有DER字符串构造私钥,请调用buildPrivateFromDer()。
// 根据现有DER字符串构建私钥
const privateKey = await keyBuilder.buildPrivateFromDer(privateKeyDer);
const publicKey = privateKey.getPublicKey();
步骤3: 创建签名上下文构建器
const builder = crypto.makeSignatureContextBuilder();
builder.signingAlgorithm = crypto.getAsymmetricAlgorithmByName(AsymmetricAlgorithm.ECDSA);
步骤4: 对消息进行签名并获取签名
// 使用私钥构建签名上下文
const signer = builder.buildSigningContext(privateKey);
const message = '这是一条非常重要的消息';
const messageBuffer = new TextEncoder().encode(message).buffer;
// 对消息签名
const signedMessage = await signer.sign(messageBuffer);
步骤5: 使用签名验证消息
// 使用公钥构建验证上下文
const verifier = builder.buildVerificationContext(publicKey);
// 验证消息
const result = await verifier.verify(messageBuffer, signedMessage);
RSA签名和验证
以下示例代码包括RSA密钥对生成、消息签名和验证。
步骤1: 创建RSA密钥构建器
// 创建RSA密钥构建器
const keybuilder = crypto.makeRsaKeyBuilder();
// 将密钥标记为可导出
keyBuilder.exportable = true;
// 设置密钥用途
keyBuilder.purposes = [KeyPurpose.SIGN, KeyPurpose.VERIFY];
步骤2: 生成密钥对
您可以生成RSA密钥对或构造私钥。
要生成RSA密钥对,请调用buildGenerated()。
// 生成RSA密钥对
const privateKey = await keyBuilder.buildGenerated();
// 获取公钥
const publicKey = privateKey.getPublicKey();
要根据现有DER字符串构造私钥,请调用buildPrivateFromDer()。
// 根据现有DER字符串构建私钥
const privateKey = await keyBuilder.buildPrivateFromDer(privateKeyDer);
const publicKey = privateKey.getPublicKey();
步骤3: 创建签名上下文构建器并对消息进行签名
通过调用buildSigningContext() 创建签名上下文构建器,然后使用RSA-PKCS1 v1.5架构对消息进行签名以获取签名。
// 使用私钥构建签名上下文
const builder = crypto.makeRsassaPkcs1ContextBuilder();
const digestAlgorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
builder.digestAlgorithm = digestAlgorithm;
const rsaPkcs1Signer = builder.buildSigningContext(privateKey);
const message = '这是一条非常重要的消息';
const messageBuffer = new TextEncoder().encode(message).buffer;
// 对消息签名
const signedMessage = await rsaPkcs1Signer.sign(messageBuffer);
步骤4: 验证消息
通过调用使用RSA-PKCS1 v1.5标准的rsaPkcs1Verifier.verify() 来使用签名进行消息验证。
// 使用公钥构建验证上下文
const rsaPkcs1Verifier = builder.buildVerificationContext(publicKey);
// 验证消息
const result = await rsaPkcs1Verifier.verify(messageBuffer, signedMessage);
步骤5: 对消息签名并获得签名
要使用RSA-PSS标准对消息进行签名,请调用rsaPssSigner.sign(),它会返回已签名消息的签名。
// 为了保证填充机制正确并提升安全性,盐值的长度通常应与摘要长度保持一致。
// 使用不同的盐值长度可能也能工作,但不建议这样做。
builder.saltLength = digestAlgorithm.size / 8;
// 使用私钥构建签名上下文
const rsaPssSigner = builder.buildSigningContext(privateKey);
const message = '这是一条非常重要的消息';
const messageBuffer = new TextEncoder().encode(message).buffer;
// 对消息签名
const signedMessage = await rsaPssSigner.sign(messageBuffer);
要验证消息,请调用rsaPssVerifier.verify() 并传递消息的签名。
// 使用公钥构建验证上下文
const rsaPssVerifier = builder.buildVerificationContext(publicKey);
// 验证消息
const result = await rsaPssVerifier.verify(messageBuffer, signedMessage);
HMAC签名和验证
以下示例说明如何生成密钥、导出密钥、对数据签名并进行验证。
// 生成密钥
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
keyBuilder.bits = 256;
const key = await keyBuilder.buildGenerated();
// 导出密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 获取摘要算法
const digestAlgorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
// 使用密钥和摘要算法创建HMAC上下文构建器
const builder = crypto.makeHmacContextBuilder();
builder.key = key;
builder.digestAlgorithm = digestAlgorithm;
// 对数据签名
const signContext = builder.build();
const tag = await signContext.sign(plaintext);
// 验证数据
const verifyContext = builder.build();
const tag = signContext.sign(plaintext);
const result1 = await verifyContext.verify(plaintext, tag);
// 尝试使用导出的密钥进行验证
const exportedBuilder = crypto.makeHmacContextBuilder();
exportedBuilder.key = exportedKey;
exportedBuilder.digestAlgorithm(digestAlgorithm);
const exportedVerifyContext = exportedBuilder.build();
const result2 = await exportedVerifyContext.verify(plaintext, tag);
使用AES CBC分组密码对消息进行加密
以下示例说明如何生成AES-256密钥、导出密钥、创建AES-256 CBC密码上下文构建器,以及如何使用它对明文进行加密。
// 生成AES-256密钥
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.bits = 256;
keyBuilder.exportable = true;
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
keyBuilder.purposes = purposes;
const key = await keyBuilder.buildGenerated();
// 导出AES密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = purposes;
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 创建AES-256 CBC密码上下文构建器
const builder = crypto.makeCbcCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
// 设置正确的IV
const iv = new Uint8Array(builder.ivSize).buffer;
builder.iv = iv;
// 设置密钥
builder.key = key;
// 加密明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const encryptionContext = builder.buildEncryptionContext();
const ciphertext = await encryptionContext.encrypt(plaintextBuffer);
// 将密文解密
const decryptionContext = builder.buildDecryptionContext();
const decrypted = await decryptionContext.decrypt(ciphertext);
const result1 = plaintext === new TextDecoder('utf-8').decode(decrypted);
// 尝试使用导出的密钥然后用它将密文解密
const exportedBuilder = crypto.makeCbcCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
exportedBuilder.iv = iv;
exportedBuilder.key = exportedKey;
const exportedDecryptionContext = exportedBuilder.buildDecryptionContext();
const exportedDecrypted = await exportedDecryptionContext.decrypt(ciphertext);
使用AES CTR分组密码对消息进行加密
以下示例说明如何生成AES-CTR密钥、导出密钥、创建AES-256 CTR密码上下文构建器,以及如何使用它对明文进行加密。
// 生成AES-256密钥
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = purposes;
keyBuilder.bits = 256;
const key = await keyBuilder.buildGenerated();
// 导出AES密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = purposes;
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 创建AES CTR密码上下文构建器
const builder = crypto.makeCtrCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
// 设置正确的计数和随机数
builder.count = 12;
builder.nonce = 12;
// 设置密钥
builder.key = key;
// 加密明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const encryptionContext = builder.buildEncryptionContext();
const ciphertext = await encryptionContext.encrypt(plaintextBuffer);
// 将密文解密
const decryptionContext = builder.buildDecryptionContext();
const decrypted = await decryptionContext.decrypt(ciphertext);
const result1 = plaintext === new TextDecoder('utf-8').decode(decrypted);
// 将导出的密钥与CTR密码上下文构建器一起使用
builder.key = exportedKey;
// 尝试使用导出的密钥解密
const exportedDecryptionContext = builder.buildDecryptionContext();
const exportedDecrypted = await exportedDecryptionContext.decrypt(ciphertext);
const result2 = plaintext === new TextDecoder('utf-8').decode(exportedDecrypted);
使用AES GCM分组密码对消息进行加密
以下示例说明如何生成AES-256 GCM密钥、导出密钥、创建AES-256 GCM密码上下文构建器,以及如何使用它对明文进行加密。
// 生成AES-256密钥
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = purposes;
keyBuilder.bits = 256;
const key = await keyBuilder.buildGenerated();
// 导出AES密钥
const rawKey = key.exportRaw();
const exportedKeyBuilder = crypto.makeSymmetricKeyBuilder();
exportedKeyBuilder.exportable = true;
exportedKeyBuilder.purposes = purposes;
const exportedKey = await exportedKeyBuilder.buildFromRaw(rawKey);
// 创建AES-256 GCM密码上下文构建器
const builder = crypto.makeGcmCipherContextBuilder(crypto.getSymmetricAlgorithmByName(SymmetricAlgorithm.AES256));
// 使用4字节标识符初始化IV以使用随机化的
// 随机数序列。或者,使用大小为builder.getIvSize() 的向量对其进行初始化
// 以使用任意随机数。
const iv = new Uint8Array([0xab, 0xcd, 0xef, 0x01]);
builder.iv = iv;
builder.key = key;
// 加密明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const encryptionContext = builder.buildEncryptionContext();
const ciphertext = await encryptionContext.encrypt(plaintextBuffer);
// 将密文解密
const decryptionContext = builder.buildDecryptionContext();
const decrypted = await decryptionContext.decrypt(ciphertext);
// 将导出的密钥与GCM密码上下文构建器一起使用
builder.key = exportedKey;
// 尝试使用导出的密钥解密
const exportedDecryptionContext = builder.buildDecryptionContext();
const exportedDecrypted = await exportedDecryptionContext.decrypt(ciphertext);
使用RSA-OAEP加密消息
以下示例说明如何生成RSA-OAEP密钥、导出密钥、创建上下文构建器,以及如何使用它对明文进行加密。
// 获取摘要算法和非对称算法,并定义密钥用途
const sha = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA384);
const alg = crypto.getAsymmetricAlgorithmByName(AsymmetricAlgorithm.RSA_OAEP);
const purposes = [KeyPurpose.ENCRYPT, KeyPurpose.DECRYPT];
// 创建一个RsaOaepKeyBuilder
const keyBuilder = crypto.makeRsaOaepKeyBuilder();
keyBuilder.exportable = true;
keyBuilder.purposes = purposes;
keyBuilder.bits = 384;
// 从密钥构建器生成私钥
const privateKey = await keyBuilder.buildGenerated();
// 导出密钥供以后的测试案例使用
const rawPrivateKey = await privateKey.exportDer();
// 获取对应的公钥
const publicKey = privateKey.getPublicKey();
// 导出公钥以备后用
const rawPublicKey = await publickey.exportDer();
// 根据消息构建明文
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
// 使用alg和sha构建RSA-OAEP密码上下文
const rsaOaepCipherContext = crypto.makeRsaOaepCipherContextBuilder(alg, sha);
// 使用公钥基于RSA-OAEP密码上下文构建加密上下文
const rsaOaepEncryptionContext = rsaOaepCipherContext.buildEncryptionContext(publickey);
// 使用加密上下文加密
const ciphertext = await rsaOaepEncryptionContext.encrypt(plaintextBuffer);
// 基于密码上下文构建解密上下文
const rsaOaepDecryptionContext = rsaOaepCipherContext.buildDecryptionContext(privatekey);
// 使用解密上下文进行解密
const decrypted = await rsaOaepDecryptionContext.decrypt(ciphertext);
// 确保解密后的消息与明文相同
const result1 = plaintext === new TextDecoder('utf-8').decode(decrypted);
// 使用导出的密钥来构建私钥和公钥
const exportedPrivkey = await keyBuilder.buildPrivateFromDer(rawPrivateKey);
const exportedRsaOaepDecryptionContext = rsaOaepCipherContext.buildDecryptionContext(exportedPrivkey);
// 使用导入的密钥解密密文并确保解密后的消息与明文一致
const exportedDecrypted = await exportedRsaOaepDecryptionContext.decrypt(ciphertext);
const result2 = plaintext === new TextDecoder('utf-8').decode(exportedDecrypted);
// 使用导入的公钥进行加密,使用原始私钥进行解密
// 并确保解密后的消息与明文一致
const exportedPublicKey = await keyBuilder.buildPublicFromDer(rawPublicKey);
const exportedRsaOaepEncryptionContext = rsaOaepCipherContext.buildEncryptionContext(exportedPublicKey);
const exportedCiphertext = await exportedRsaOaepEncryptionContext.encrypt(plaintextBuffer);
const exportedDecryptedAgain = await rsaOaepDecryptionContext.decrypt(exportedCiphertext);
const result3 = plaintext === new TextDecoder('utf-8').decode(exportedDecryptedAgain);
创建消息摘要
以下代码示例调用getDigestAlgorithmByName() 来获取摘要,创建摘要上下文,对示例字符串进行编码,并获取该字符串的摘要。
const builder = crypto.makeDigestContextBuilder();
builder.digestAlgorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
const digestContext = builder.build();
const plaintext = '使用此字符串';
const plaintextBuffer = new TextEncoder().encode(plaintext).buffer;
const hash = await digestContext.digest(plaintextBuffer);
使用HKDF(HMAC密钥派生函数)派生密钥
const salt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const info = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // 来自密钥的额外信息
// 创建密钥(如果您已经有了一个用于DERIVE的密钥,则为可选项)
const keyBuilder = crypto.makeSymmetricKeyBuilder();
keyBuilder.bits = 256; // 任意长度
keyBuilder.exportable = false;
keyBuilder.purposes = [KeyPurpose.DERIVE]; // 重要须知:密钥必须能够派生
const secret = await keyBuilder.buildGenerated();
const algorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
// 创建上下文构建器
const ctxBuilder = crypto.makeHkdfContextBuilder();
ctxBuilder.info = info;
ctxBuilder.salt = salt;
ctxBuilder.hashAlgorithm = algorithm;
// 创建派生上下文
const ctx = ctxBuilder.buildKeyDerivationContext(secret);
// 派生对称密钥
// 重要须知:派生的密钥必须与所用算法的长度相匹配
const generatedKeyLen = algorithm.size / 8;
const symmKey = ctx.deriveKey(generatedKeyLen);
// 改为派生一个原始密钥
const rawKey = ctx.deriveBits(generatedKeyLen);
使用PBKDF2(基于密码的密钥派生函数2)派生密钥
const iterations = 10000; // 迭代次数。值越高越安全,但性能越低。
// 10000是一个合理的值,不会导致性能下降太多
const salt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const generatedKeyLen = 512;
// 创建上下文构建器
const ctxBuilder = crypto.makePbkdf2ContextBuilder();
// 创建密钥(如果您已经有了一个用于DERIVE的密钥,则为可选项)
const keyBuilder = crypto.makeSymmetricKeyBuilder()
keyBuilder.bits = 256; // 任意长度
keyBuilder.exportable = false;
keyBuilder.purposes = [KeyPurpose.DERIVE]; // 重要须知:密钥必须能够派生
const secret = await keyBuilder.buildGenerated();
const algorithm = crypto.getDigestAlgorithmByName(DigestAlgorithm.SHA256);
// 创建派生上下文
ctxBuilder.iterations = iterations;
ctxBuilder.salt = salt;
ctxBuilder.hashAlgorithm = algorithm;
const ctx = buildKeyDerivationContext(secret);
// 派生对称密钥
const symmKey = await ctx.deriveKey(generatedKeyLen);
// 改为派生一个原始密钥
const rawKey = await ctx.deriveBits(generatedKeyLen);
网页加密API shim层
KeplerCrypto库提供了一个shim层,用于实现网页加密API(仅提供英文版)。有关API方法和参数,请参阅现有的网页加密API MDN文档。
网页加密用法示例
以下示例介绍如何导入和使用网页加密API shim层:
导入API
import {WebCrypto} from '@amazon-devices/keplercrypto';
初始化WebCrypto对象
const wc = new WebCrypto();
可选: 在globalThis上公开crypto实例
// 如果globalThis不存在,则定义它
if (typeof globalThis === 'undefined') {
(window as any).globalThis = window;
}
globalThis.crypto = wc.crypto as any;
调用网页加密API
下一个代码示例生成ECDH CryptoKeyPair:
const nonExtractableKeyPair = (await wc.crypto.subtle.generateKey(
{
name: 'ECDH',
namedCurve: 'P-256',
},
false, // 不可提取
['deriveBits'],
)) as CryptoKeyPair;
支持的网页加密算法
该库仍在开发中,网页加密实现仅提供整个W3C网页加密规范的一个子集。未来版本将支持更多操作。
网页加密支持的密钥格式
使用网页加密API导入和导出密钥时,支持以下格式:
| 密钥类型 | 支持的导入格式 | 支持的导出格式 |
|---|---|---|
| AES | raw、jwk | raw、jwk |
| HMAC | raw、jwk | raw、jwk |
| ECDH | pkcs8、spki、jwk | pkcs8、spki、jwk |
| ECDSA | pkcs8、spki、jwk | pkcs8、spki、jwk |
| HKDF | raw | raw |
| PBKDF2 | raw | raw |
| RSASSA-PKCS1-v1_5 | pkcs8、spki、jwk | pkcs8、spki、jwk |
| RSA-PSS | pkcs8、spki、jwk | pkcs8、spki、jwk |
| RSA-OAEP | pkcs8、spki、jwk | pkcs8、spki、jwk |
格式描述:
- raw: 未格式化的二进制数据,用于对称密钥或椭圆曲线公钥。
- pkcs8: RSA或椭圆曲线私钥的PKCS #8格式。
- spki: RSA或椭圆曲线公钥的SubjectPublicKeyInfo格式。
- jwk: 对称密钥或RSA和椭圆曲线公钥/私钥的JSON网页密钥格式。
导入密钥的示例:
// 导入原始格式的AES密钥
const rawKey = new Uint8Array([...]); // 您的密钥字节
const importedKey = await wc.crypto.subtle.importKey(
"raw", // 格式
rawKey, // 密钥数据
{ name: "AES-GCM" }, // 算法
false, // 可提取
["encrypt", "decrypt"] // 密钥用法
);
网页加密API支持矩阵
算法操作:
- ✓ = 支持
- ✗ = 不支持
- — = 不适用
| 算法 | encrypt() | decrypt() | sign() | verify() | digest() | importKey() | exportKey() | generateKey() | deriveBits() | deriveKey() | wrapKey() | unwrapKey() |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RSASSA-PKCS1v1 | — | — | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — | — | — |
| RSA-PSS | — | — | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — | — | — |
| RSA-OAEP | ✓ | ✓ | — | — | — | ✓ | ✓ | ✓ | — | — | ✗ | ✗ |
| ECDH | — | — | — | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | — | — |
| ECDSA | — | — | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — | — | — |
| AES-CTR | ✓ | ✓ | — | — | — | ✓ | ✓ | ✓ | — | — | ✗ | ✗ |
| AES-CBC | ✓ | ✓ | — | — | — | ✓ | ✓ | ✓ | — | — | ✗ | ✗ |
| AES-GCM | ✓ | ✓ | — | — | — | ✓ | ✓ | ✓ | — | — | ✗ | ✗ |
| AES-KW | — | — | — | — | — | ✗ | ✗ | ✗ | — | — | ✗ | ✗ |
| HMAC | — | — | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — | — | — |
| HKDF | — | — | — | — | — | ✓ | ✓ | — | ✓ | ✓ | — | — |
| PBKDF2 | — | — | — | — | — | ✓ | ✓ | — | ✓ | ✓ | — | — |
| Ed25519 | — | — | ✗ | ✗ | — | ✗ | ✗ | ✗ | — | — | — | — |
| X25519 | — | — | — | — | — | ✗ | ✗ | ✗ | ✗ | ✗ | — | — |
| SHA-1 | — | — | — | — | ✗ | — | — | — | — | — | — | — |
| SHA-256 | — | — | — | — | ✓ | — | — | — | — | — | — | — |
| SHA-384 | — | — | — | — | ✓ | — | — | — | — | — | — | — |
| SHA-512 | — | — | — | — | ✓ | — | — | — | — | — | — | — |
模块
- Crypto
- index
- turbo-modules/__mocks__/KeplerCrypto
- turbo-modules/__mocks__/KeplerCrypto
- turbo-modules/__mocks__/KeplerCrypto
- turbo-modules/KeplerCrypto
- turbo-modules/KeplerCrypto
- webcrypto/Crypto
- webcrypto/Crypto
- webcrypto/errors
- webcrypto/errors
- webcrypto/SubtleCrypto
- webcrypto/SubtleCrypto
- webcrypto/types
- webcrypto/types
- webcrypto/WebCrypto
- webcrypto/WebCrypto
Last updated: 2025年10月2日

