HarmonyOS 鸿蒙Next RSA加解密单项使用,如何使用RSA加解密双项功能。
RSA加解密单项使用,如何使用RSA加解密双项功能。
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';
// 分段加密消息
async function rsaEncryptBySegment(pubKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher('RSA1024|PKCS1');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);
let plainTextSplitLen = 64;
let cipherText = new Uint8Array();
for (let i = 0; i < plainText.data.length; i += plainTextSplitLen ) {
let updateMessage = plainText.data.subarray(i, i + plainTextSplitLen );
let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
// 将原文按64字符进行拆分,循环调用doFinal进行加密,使用1024bit密钥时,每次加密生成128字节长度的密文
let updateOutput = await cipher.doFinal(updateMessageBlob);
let mergeText = new Uint8Array(cipherText.length + updateOutput.data.length);
mergeText.set(cipherText);
mergeText.set(updateOutput.data, cipherText.length);
cipherText = mergeText;
}
let cipherBlob: cryptoFramework.DataBlob = { data: cipherText };
return cipherBlob;
}
// 分段解密消息
async function rsaDecryptBySegment(priKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) {
let decoder = cryptoFramework.createCipher('RSA1024|PKCS1');
await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, priKey, null);
let cipherTextSplitLen = 128; // RSA密钥每次加密生成的密文字节长度计算方式:密钥位数/8
let decryptText = new Uint8Array();
for (let i = 0; i < cipherText.data.length; i += cipherTextSplitLen) {
let updateMessage = cipherText.data.subarray(i, i + cipherTextSplitLen);
let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
// 将密文按128字节进行拆分解密,得到原文后进行拼接
let updateOutput = await decoder.doFinal(updateMessageBlob);
let mergeText = new Uint8Array(decryptText.length + updateOutput.data.length);
mergeText.set(decryptText);
mergeText.set(updateOutput.data, decryptText.length);
decryptText = mergeText;
}
let decryptBlob: cryptoFramework.DataBlob = { data: decryptText };
return decryptBlob;
}
async function rsaEncryptLongMessage() {
let message = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!";
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024"); // 创建非对称密钥生成器对象
let keyPair = await asyKeyGenerator.generateKeyPair(); // 随机生成RSA密钥
let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
let encryptText = await rsaEncryptBySegment(keyPair.pubKey, plainText);
let decryptText = await rsaDecryptBySegment(keyPair.priKey, encryptText);
if (plainText.data.toString() === decryptText.data.toString()) {
console.info('decrypt ok');
console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));
} else {
console.error('decrypt failed');
}
}
假定后端提供一个base64的公钥给到客户端,客户端使用公钥进行加密,加密字段通过接口上送给服务端,服务端用私钥进行解密,但是服务端把接口返回的数据用私钥加密返回给客户端,客户端如何使用公钥进行解密呢?
我看官方文档没有这种场景,都是公钥加密,私钥解密场景,没看到私钥加密,公钥解密的场景。
更多关于HarmonyOS 鸿蒙Next RSA加解密单项使用,如何使用RSA加解密双项功能。的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
目前已支持RSA私钥加密,公钥解密,1楼为异步方法实现,补充demo为同步方法实现:
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer, util } from '@kit.ArkTS';
@Entry
@Component
struct RSAReverseCrypto {
@State message: string = '点击开始';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
RsaReverse()
})
}
.width('100%')
}
.height('100%')
}
}
// 字符串转成字节流
export function stringToUint8Array(str: string) {
return new Uint8Array(buffer.from(str,'utf-8').buffer);
}
// Uint8Array转成String
function uint8ArrayToString(input: Uint8Array): string {
let textDecoder = util.TextDecoder.create('utf-8');
return textDecoder.decodeWithStream(input);
}
// 公钥解密
function verifyMessage(pubKey: cryptoFramework.PubKey,signMessageBlob: cryptoFramework.DataBlob) {
let verifyAlg = "RSA2048|PKCS1|NoHash|Recover";
let verifier = cryptoFramework.createVerify(verifyAlg);
verifier.initSync(pubKey);
let rawSignData = verifier.recoverSync(signMessageBlob);
console.log("rsa puk data " + uint8ArrayToString(rawSignData?.data))
return rawSignData;
}
//私钥加密
function signMessage(priKey: cryptoFramework.PriKey, plainText:cryptoFramework.DataBlob) {
let signAlg = "RSA2048|PKCS1|NoHash|OnlySign";
let signer = cryptoFramework.createSign(signAlg);
signer.initSync(priKey);
let signData = signer.signSync(plainText);
return signData;
}
// 密钥转换
function genKeyPairByData(pubKeyData: Uint8Array, priKeyData: Uint8Array) {
let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyData };
let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyData };
let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024');
let keyPair = rsaGenerator.convertKeySync(pubKeyBlob, priKeyBlob);
console.info('convertKey success');
return keyPair;
}
//Rsa 加解密
function RsaReverse() {
let pkData = new Uint8Array([48, 129, 159, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 141, 0, 48, 129, 137, 2, 129, 129, 0, 197, 64, 10, 198, 14, 110, 65, 92, 206, 35, 28, 123, 153, 24, 134, 255, 145, 74, 42, 173, 40, 215, 146, 58, 143, 46, 10, 195, 154, 160, 69, 196, 220, 152, 179, 44, 111, 200, 84, 78, 215, 73, 210, 181, 12, 29, 70, 68, 36, 135, 153, 89, 230, 202, 130, 212, 111, 243, 234, 92, 131, 62, 145, 50, 73, 48, 104, 245, 46, 70, 45, 157, 147, 143, 140, 162, 156, 216, 220, 49, 121, 142, 194, 33, 223, 201, 0, 16, 163, 210, 240, 118, 92, 147, 121, 220, 17, 114, 24, 52, 125, 135, 176, 88, 21, 83, 86, 17, 156, 88, 250, 48, 79, 86, 128, 248, 105, 208, 133, 140, 13, 153, 164, 191, 136, 164, 44, 53, 2, 3, 1, 0, 1]);
let skData = new Uint8Array([48, 130, 2, 119, 2, 1, 0, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 2, 97, 48, 130, 2, 93, 2, 1, 0, 2, 129, 129, 0, 197, 64, 10, 198, 14, 110, 65, 92, 206, 35, 28, 123, 153, 24, 134, 255, 145, 74, 42, 173, 40, 215, 146, 58, 143, 46, 10, 195, 154, 160, 69, 196, 220, 152, 179, 44, 111, 200, 84, 78, 215, 73, 210, 181, 12, 29, 70, 68, 36, 135, 153, 89, 230, 202, 130, 212, 111, 243, 234, 92, 131, 62, 145, 50, 73, 48, 104, 245, 46, 70, 45, 157, 147, 143, 140, 162, 156, 216, 220, 49, 121, 142, 194, 33, 223, 201, 0, 16, 163, 210, 240, 118, 92, 147, 121, 220, 17, 114, 24, 52, 125, 135, 176, 88, 21, 83, 86, 17, 156, 88, 250, 48, 79, 86, 128, 248, 105, 208, 133, 140, 13, 153, 164, 191, 136, 164, 44, 53, 2, 3, 1, 0, 1, 2, 129, 128, 70, 75, 184, 139, 53, 1, 94, 17, 240, 244, 218, 101, 193, 253, 215, 190, 164, 204, 197, 192, 200, 89, 107, 39, 171, 119, 65, 38, 204, 168, 105, 180, 234, 217, 16, 161, 185, 132, 175, 103, 25, 154, 153, 153, 36, 36, 26, 178, 150, 66, 45, 8, 185, 19, 90, 228, 210, 177, 30, 200, 177, 141, 78, 184, 248, 59, 113, 154, 145, 73, 160, 24, 73, 157, 86, 207, 186, 32, 95, 200, 106, 252, 107, 69, 170, 193, 216, 196, 181, 142, 74, 203, 15, 18, 89, 228, 152, 19, 239, 21, 233, 98, 121, 214, 57, 187, 111, 239, 223, 248, 199, 70, 223, 108, 108, 113, 234, 144, 155, 95, 246, 144, 244, 122, 39, 55, 127, 81, 2, 65, 0, 246, 96, 188, 0, 0, 104, 221, 105, 139, 144, 63, 175, 209, 87, 179, 162, 88, 192, 99, 82, 125, 53, 54, 48, 70, 245, 239, 37, 15, 242, 247, 84, 115, 187, 196, 95, 156, 40, 165, 60, 64, 102, 13, 229, 243, 2, 149, 0, 232, 226, 221, 192, 95, 11, 12, 208, 5, 181, 98, 62, 210, 190, 141, 235, 2, 65, 0, 204, 244, 34, 10, 105, 80, 76, 116, 163, 35, 231, 168, 187, 206, 189, 101, 215, 103, 80, 115, 86, 11, 34, 127, 203, 114, 84, 188, 121, 174, 169, 31, 142, 2, 182, 27, 140, 225, 157, 227, 71, 98, 15, 203, 187, 213, 5, 190, 20, 121, 8, 30, 193, 100, 232, 101, 141, 8, 124, 20, 29, 78, 6, 95, 2, 65, 0, 204, 43, 225, 224, 6, 118, 224, 117, 100, 200, 199, 94, 70, 23, 109, 175, 173, 232, 208, 230, 61, 8, 105, 189, 156, 48, 150, 91, 154, 89, 248, 136, 173, 215, 254, 166, 84, 220, 130, 1, 234, 68, 40, 100, 84, 251, 224, 202, 254, 51, 115, 28, 198, 38, 124, 25, 175, 129, 94, 199, 61, 17, 216, 189, 2, 64, 72, 230, 129, 129, 48, 138, 134, 87, 106, 123, 231, 247, 165, 173, 216, 194, 115, 198, 228, 223, 209, 120, 46, 114, 68, 92, 75, 117, 170, 214, 140, 131, 147, 208, 181, 19, 193, 157, 178, 186, 87, 246, 178, 101, 166, 79, 20, 54, 211, 51, 101, 199, 2, 197, 48, 192, 134, 84, 193, 69, 170, 82, 201, 131, 2, 65, 0, 213, 165, 55, 166, 131, 210, 195, 56, 250, 147, 195, 61, 205, 208, 189, 185, 40, 52, 50, 119, 137, 23, 246, 46, 220, 108, 52, 23, 152, 154, 94, 32, 144, 195, 184, 249, 21, 168, 12, 57, 222, 18, 60, 117, 81, 157, 72, 30, 155, 190, 165, 242, 228, 139, 240, 184, 145, 170, 103, 210, 160, 161, 135, 13]);
let keyPair = genKeyPairByData(pkData, skData);
let pubKey = keyPair.pubKey
let priKey = keyPair.priKey
let message = "This is a test";
let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
let encryptText = signMessage(priKey, plainText);
let decryptText = verifyMessage(pubKey, encryptText);
console.info('decrypt plainText: ' + buffer.from(decryptText?.data).toString('utf-8'));
if (plainText.data.toString() === decryptText?.data.toString()) {
console.info('decrypt ok');
} else {
console.error('decrypt failed');
}
}
更多关于HarmonyOS 鸿蒙Next RSA加解密单项使用,如何使用RSA加解密双项功能。的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
目前是已支持RSA私钥加密,公钥解密,其实现可参考如下代码实现:
//私钥加密
async function signMessagePromise(priKey: cryptoFramework.PriKey) {
let signAlg = "RSA1024|PKCS1|NoHash|OnlySign";
let signer = cryptoFramework.createSign(signAlg);
await signer.init(priKey);
let signData = await signer.sign({data: new Uint8Array(buffer.from("This is Sign test plan2", 'utf-8').buffer) });
return signData;
}
// 公钥解密
async function verifyMessagePromise(signMessageBlob: cryptoFramework.DataBlob, pubKey: cryptoFramework.PubKey) {
let verifyAlg = "RSA1024|PKCS1|NoHash|Recover";
let verifier = cryptoFramework.createVerify(verifyAlg);
await verifier.init(pubKey);
let rawSignData = await verifier.recover(signMessageBlob);
return rawSignData;
}
在HarmonyOS(鸿蒙)系统中实现RSA加解密双项功能,可以通过以下步骤进行:
-
导入加密库:首先,确保你的项目中已经导入了支持RSA加密的库。鸿蒙系统通常自带安全模块,你可以利用这些模块进行RSA加密操作。
-
生成密钥对:使用鸿蒙系统提供的API生成RSA密钥对,包括公钥和私钥。这是实现双向加密解密的基础。
-
加密过程:使用生成的公钥对数据进行加密。鸿蒙的加密API允许你指定加密算法和填充模式,确保加密过程的安全性。
-
解密过程:使用生成的私钥对加密后的数据进行解密。解密过程同样需要指定正确的算法和填充模式。
-
错误处理:在加密和解密过程中,需要添加错误处理逻辑,以应对可能的异常情况,如密钥不匹配、数据损坏等。
-
测试:编写测试用例,验证RSA双项功能的正确性。确保加密后的数据能够成功解密,解密后的数据与原始数据一致。
在鸿蒙系统中,RSA双项功能的实现主要依赖于系统提供的安全模块和API。如果你已经按照上述步骤操作,但仍然遇到问题,请直接联系官网客服。官网地址是:https://www.itying.com/category-93-b0.html ,他们将为你提供更专业的帮助。