HarmonyOS鸿蒙Next中androdi中的rsa加密代码怎么转换成arkts代码
HarmonyOS鸿蒙Next中androdi中的rsa加密代码怎么转换成arkts代码
代码如下
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
public class RSA {
public static final String CHAR_ENCODING = "UTF-8";
public static final String RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";
private static int KEYSIZE = 1024;
/**
* 生成密钥对
*/
public static Map<String, String> generateKeyPair() throws Exception {
/** RSA算法要求有一个可信任的随机数源 */
SecureRandom sr = new SecureRandom();
/** 为RSA算法创建一个KeyPairGenerator对象 */
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
/** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
kpg.initialize(KEYSIZE, sr);
/** 生成密匙对 */
KeyPair kp = kpg.generateKeyPair();
/** 得到公钥 */
Key publicKey = kp.getPublic();
byte[] publicKeyBytes = publicKey.getEncoded();
String pub = new String(Base64.encodeBase64(publicKeyBytes),
CHAR_ENCODING);
/** 得到私钥 */
Key privateKey = kp.getPrivate();
byte[] privateKeyBytes = privateKey.getEncoded();
String pri = new String(Base64.encodeBase64(privateKeyBytes),
CHAR_ENCODING);
Map<String, String> map = new HashMap<>();
map.put("publicKey", pub);
map.put("privateKey", pri);
RSAPublicKey rsp = (RSAPublicKey) kp.getPublic();
BigInteger bint = rsp.getModulus();
byte[] b = bint.toByteArray();
byte[] deBase64Value = Base64.encodeBase64(b);
String retValue = new String(deBase64Value);
map.put("modulus", retValue);
return map;
}
/**
* 加密方法
* @param source 源数据
* @param publicKey 公匙
* @return Base64URLNoPaddingEncode 后的加密byte[]
* @throws Exception
*/
public static String encrypt(String source, String publicKey, int publicKeySize)
throws Exception {
if(publicKeySize == 0 || source.getBytes().length <= getMaxBlockSize(publicKeySize)){
return encryptByPublicKey(source, publicKey);
}
return new String(android.util.Base64.encode(encryptByPublicKeyBySpilt(source.getBytes(), publicKey.getBytes(), publicKeySize, RSA_ALGORITHM, true),
android.util.Base64.NO_PADDING | android.util.Base64.URL_SAFE | android.util.Base64.NO_WRAP));
}
private static String encryptByPublicKey(String source, String publicKey) throws Exception{
Key key = getPublicKey(publicKey);
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] b = source.getBytes();
byte[] b1 = cipher.doFinal(b);
return new String(android.util.Base64.encode(b1,
android.util.Base64.NO_PADDING | android.util.Base64.URL_SAFE | android.util.Base64.NO_WRAP));
}
private static byte[] encryptByPublicKeyBySpilt(final byte[] data,
final byte[] key,
final int keySize,
final String transformation,
final boolean isEncrypt) throws Exception{
if (data == null || data.length == 0 || key == null || key.length == 0) {
return null;
}
Key rsaKey;
if (isEncrypt) {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(android.util.Base64.decode(key, android.util.Base64.NO_PADDING));
rsaKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
} else {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(android.util.Base64.decode(key, android.util.Base64.NO_PADDING));
rsaKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
}
if (rsaKey == null) {
return null;
}
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, rsaKey);
int len = data.length;
int maxLen = keySize / 8;
if (isEncrypt) {
String lowerTrans = transformation.toLowerCase();
if (lowerTrans.endsWith("pkcs1padding")) {
maxLen -= 11;
}
}
int count = len / maxLen;
if (count > 0) {
byte[] ret = new byte[0];
byte[] buff = new byte[maxLen];
int index = 0;
for (int i = 0; i < count; i++) {
System.arraycopy(data, index, buff, 0, maxLen);
ret = joins(ret, cipher.doFinal(buff));
index += maxLen;
}
if (index != len) {
int restLen = len - index;
buff = new byte[restLen];
System.arraycopy(data, index, buff, 0, restLen);
ret = joins(ret, cipher.doFinal(buff));
}
return ret;
} else {
return cipher.doFinal(data);
}
}
private static byte[] encryptByPublicKeyBySpilt2(final byte[] data,
final byte[] key,
final int keySize,
final String transformation,
final boolean isEncrypt) throws Exception{
if (rsaKey == null) {
return null;
}
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, rsaKey);
int len = data.length;
int maxLen = keySize / 8;
if (isEncrypt) {
String lowerTrans = transformation.toLowerCase();
if (lowerTrans.endsWith("pkcs1padding")) {
maxLen -= 11;
}
}
int count = len / maxLen;
if (count > 0) {
byte[] ret = new byte[0];
byte[] buff = new byte[maxLen];
int index = 0;
for (int i = 0; i < count; i++) {
System.arraycopy(data, index, buff, 0, maxLen);
ret = joins(ret, cipher.doFinal(buff));
index += maxLen;
}
if (index != len) {
int restLen = len - index;
buff = new byte[restLen];
System.arraycopy(data, index, buff, 0, restLen);
ret = joins(ret, cipher.doFinal(buff));
}
return ret;
} else {
return cipher.doFinal(data);
}
}
private static byte[] joins(final byte[] prefix, final byte[] suffix) {
byte[] ret = new byte[prefix.length + suffix.length];
System.arraycopy(prefix, 0, ret, 0, prefix.length);
System.arraycopy(suffix, 0, ret, prefix.length, suffix.length);
return ret;
}
private static int getMaxBlockSize(int keySize){
return (keySize / 8) - 11;
}
/**
* 解密算法 cryptograph:密文
*/
public static String decrypt(String cryptograph, String privateKey)
throws Exception {
Key key = getPrivateKey(privateKey);
/** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] b1 = Base64.decodeBase64(cryptograph.getBytes());
/** 执行解密操作 */
byte[] b = cipher.doFinal(b1);
return new String(b);
}
/**
* 得到公钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(
android.util.Base64.decode(key.getBytes(), android.util.Base64.NO_PADDING));
// Base64.decodeBase64(key.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/**
* 得到私钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
Base64.decodeBase64(key.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
public static String sign(String content, String privateKey) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
Base64.decodeBase64(privateKey.getBytes()));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
Signature signature = Signature.getInstance("SHA1WithRSA");
signature.initSign(priKey);
signature.update(content.getBytes(CHAR_ENCODING));
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed));
} catch (Exception e) {
}
return null;
}
public static boolean checkSign(String content, String sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decode2(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature
.getInstance("SHA1WithRSA");
signature.initVerify(pubKey);
signature.update(content.getBytes("utf-8"));
boolean bverify = signature.verify(Base64.decode2(sign));
return bverify;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
更多关于HarmonyOS鸿蒙Next中androdi中的rsa加密代码怎么转换成arkts代码的实战教程也可以访问 https://www.itying.com/category-93-b0.html
4 回复
以下是关键转换步骤及示例:
一、核心API对比
Android Java API | ArkTS API | 功能差异说明 |
---|---|---|
KeyFactory.getInstance(“RSA”) | cryptoFramework.createAsyKeyGenerator | 密钥生成器创建方式不同 |
X509EncodedKeySpec | cryptoFramework.DataBlob + convertKey | 公钥需通过二进制数据转换 |
Cipher.getInstance(“RSA/ECB/PKCS1Padding”) | createCipher('RSA1024 | PKCS1’) |
二、代码转换示例
1. 公钥处理转换
Android原生代码:
byte[] publicBytes = Base64.decode(pubKeyStr, Base64.DEFAULT);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
ArkTS等价实现:
import { util, buffer } from '@kit.ArkTS';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
const base64Helper = new util.Base64Helper();
const pubKeyBlob: cryptoFramework.DataBlob = {
data: base64Helper.decodeSync(pubKeyStr) // Base64解码
};
// 生成密钥生成器并转换公钥
const rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA2048");
const keyPair = await rsaGenerator.convertKey(pubKeyBlob, null);
const publicKey = keyPair.pubKey; // 获得可用的公钥对象
2. 加密逻辑转换
Android原生代码:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(plainText.getBytes());
String result = Base64.encodeToString(encrypted, Base64.NO_WRAP);
ArkTS等价实现:
async function rsaEncrypt(publicKey: cryptoFramework.PubKey, plainText: string) {
// 创建加密实例
const cipher = cryptoFramework.createCipher('RSA2048|PKCS1');
// 初始化加密器
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null);
// 执行加密
const input: cryptoFramework.DataBlob = {
data: stringToUint8Array(plainText)
};
const encryptData = await cipher.doFinal(input);
// Base64编码结果
return base64Helper.encodeToStringSync(encryptData.data);
}
// 字符串转Uint8Array工具函数
function stringToUint8Array(str: string): Uint8Array {
return new Uint8Array(str.split('').map(c => c.charCodeAt(0)));
}
三、关键差异说明
- 异步编程模型:ArkTS强制使用Promise/async-await异步模式,而Android多为同步接口
- 密钥规格声明:算法参数需通过字符串拼接形式指定,如
RSA2048|PKCS1
- 数据格式处理:
- 输入数据需封装为
DataBlob
类型 - 必须显式处理Base64编解码操作
- 输入数据需封装为
- 错误处理机制:需检查
doFinal
返回结果是否为null
四、注意事项
- 密钥长度匹配:需确保createCipher和createAsyKeyGenerator指定的RSA长度一致(如RSA1024/RSA2048)
- 填充模式兼容性:Android的PKCS1Padding对应ArkTS的PKCS1模式
- 性能优化:大数据量建议采用分段加密
- 异常处理:需捕获异步操作中的异常:
try {
const result = await rsaEncrypt(publicKey, "Hello Harmony");
} catch (error) {
console.error(`Encrypt failed: ${error.code}, ${error.message}`);
}
更多关于HarmonyOS鸿蒙Next中androdi中的rsa加密代码怎么转换成arkts代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,将Android RSA加密代码转换为ArkTS代码:
- 使用
@ohos.security.cryptoFramework
模块 - 密钥生成示例:
import cryptoFramework from '@ohos.security.cryptoFramework';
let keyGen = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
keyGen.generateKeyPair((err, keyPair) => {
// 处理密钥对
});
- 加密示例:
let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);
cipher.update(dataBlob, (err, output) => {
// 处理加密数据
});
注意使用ArkTS的异步回调机制。
以下是Java RSA加密代码转换为ArkTS的实现方案:
import cryptoFramework from '@ohos.security.cryptoFramework';
import util from '@ohos.util';
class RSAUtils {
private static readonly CHAR_ENCODING = 'UTF-8';
private static readonly RSA_ALGORITHM = 'RSA1024|PKCS1';
// 生成密钥对
static async generateKeyPair(): Promise<Map<string, string>> {
const keyGen = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2');
const keyPair = await keyGen.generateKeyPair();
const pubKeyBlob = await keyPair.pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PUBLIC_KEY_SPEC);
const priKeyBlob = await keyPair.priKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PRIVATE_KEY_SPEC);
const base64 = new util.Base64Helper();
const map = new Map<string, string>();
map.set('publicKey', base64.encodeToStringSync(pubKeyBlob.data));
map.set('privateKey', base64.encodeToStringSync(priKeyBlob.data));
return map;
}
// 公钥加密
static async encrypt(source: string, publicKey: string): Promise<string> {
const base64 = new util.Base64Helper();
const pubKeyBlob = { data: base64.decodeSync(publicKey) };
const keyGen = cryptoFramework.createAsyKeyGenerator('RSA1024');
const pubKey = await keyGen.convertKey(pubKeyBlob);
const cipher = cryptoFramework.createCipher(this.RSA_ALGORITHM);
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);
const textEncoder = new util.TextEncoder();
const dataBlob = { data: textEncoder.encodeInto(source) };
const encryptedData = await cipher.doFinal(dataBlob);
return base64.encodeToStringSync(encryptedData.data);
}
// 私钥解密
static async decrypt(cryptograph: string, privateKey: string): Promise<string> {
const base64 = new util.Base64Helper();
const priKeyBlob = { data: base64.decodeSync(privateKey) };
const keyGen = cryptoFramework.createAsyKeyGenerator('RSA1024');
const priKey = await keyGen.convertKey(priKeyBlob);
const cipher = cryptoFramework.createCipher(this.RSA_ALGORITHM);
await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, priKey, null);
const encryptedBlob = { data: base64.decodeSync(cryptograph) };
const decryptedData = await cipher.doFinal(encryptedBlob);
const textDecoder = new util.TextDecoder();
return textDecoder.decodeWithStream(decryptedData.data);
}
}
主要说明:
- 使用
@ohos.security.cryptoFramework
模块替代Java的加密类 - 密钥生成使用
createAsyKeyGenerator
接口 - 加密/解密操作通过
createCipher
实现 - Base64编码使用
@ohos.util
模块 - 字符串编解码使用TextEncoder/TextDecoder
注意:ArkTS的加密API与Java有差异,部分功能如签名验证需要单独实现。