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)));
}

三、关键差异说明

  1. 异步编程模型:ArkTS强制使用Promise/async-await异步模式,而Android多为同步接口
  2. 密钥规格声明:算法参数需通过字符串拼接形式指定,如RSA2048|PKCS1
  3. 数据格式处理
    • 输入数据需封装为DataBlob类型
    • 必须显式处理Base64编解码操作
  4. 错误处理机制:需检查doFinal返回结果是否为null

四、注意事项

  1. 密钥长度匹配:需确保createCipher和createAsyKeyGenerator指定的RSA长度一致(如RSA1024/RSA2048)
  2. 填充模式兼容性:Android的PKCS1Padding对应ArkTS的PKCS1模式
  3. 性能优化:大数据量建议采用分段加密
  4. 异常处理:需捕获异步操作中的异常:
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代码:

  1. 使用@ohos.security.cryptoFramework模块
  2. 密钥生成示例:
import cryptoFramework from '@ohos.security.cryptoFramework';

let keyGen = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
keyGen.generateKeyPair((err, keyPair) => {
  // 处理密钥对
});
  1. 加密示例:
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);
  }
}

主要说明:

  1. 使用@ohos.security.cryptoFramework模块替代Java的加密类
  2. 密钥生成使用createAsyKeyGenerator接口
  3. 加密/解密操作通过createCipher实现
  4. Base64编码使用@ohos.util模块
  5. 字符串编解码使用TextEncoder/TextDecoder

注意:ArkTS的加密API与Java有差异,部分功能如签名验证需要单独实现。

回到顶部