Sca_jie 2024-04-29 18:04 采纳率: 33.3%
浏览 7
已结题

关于#android#的rsa加密和node不互通的问题,如何解决?

android作为前端,使用node生成的rsa公钥进行加密密码,然后通过接口到node后端中rsa解密密码,但是明明公钥和私钥都是正确的,但node就是无法解密android加密的密文,代码如下:
1、node生成公钥和私钥的方法:

const { publicEncrypt, privateDecrypt } = require('crypto')
const fs = require('fs')

const { generateKeyPairSync } = require('crypto')

// 配置
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
  modulusLength: 1024,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
})

// 生成密钥
const pub = publicKey.toString()
const pri = privateKey.toString()
console.log('---------------公钥--------------\n' + pub)
console.log('---------------私钥--------------\n' + pri)

// 生成pem密钥文件
fs.writeFileSync('./pem/RsaPri.pem', privateKey)
fs.writeFileSync('./pem/RsaPub.pem', publicKey)

2、node解密的方法:

// 解密
function decryption (data) {
  try {
    const priKey = fs.readFileSync('./pem/RsaPri.pem', 'utf8')
    const dataDecry = privateDecrypt(priKey, Buffer.from(data.toString('base64'), 'base64'))
    // 返回结果
    return JSON.stringify({
      code: 200,
      data: dataDecry
    })
  } catch (e) {
    // 返回错误
    return JSON.stringify({
      code: 500,
      data: e
    })
  }
}

module.exports = {
  decryption
}

3、android加密的方法

package com.example.test4.utils;

import android.os.Build;

import androidx.annotation.RequiresApi;

import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;

public class RsaUtil {

    private static String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUdql3ySffmXK62MdQcZnLjIL5n2vcavNEt/v1U//caLzyy+olyhvdKUk/sBYNApKzEIOCy5mbm3xmGEB0HplZWCAWs/lxB+827MeSWCjEwg5/kxtMFGkqiw64gp5Bx7IqwdA3qhsFlmyxIGMm/66Ea3GCjL7PTPlDoDU5ZL803wIDAQAB";

    /**
     * 使用公钥加密
     * @param content 需要加密的密文(String类型)
     * @return base64数据
     * @throws Exception
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static String encryptByPublicKey(String content) throws Exception {

        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr.getBytes("utf-8"));
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        byte[] plainTextBytes = content.getBytes("UTF-8");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainTextBytes);
        String encryptedBase64Str = Base64.getEncoder().encodeToString(encryptedBytes);
        
        System.out.println(encryptedBase64Str);
        return encryptedBase64Str;
    }
}

  • 写回答

2条回答 默认 最新

  • 码农阿豪@新空间 优质创作者: Java、后端开发技术领域 2024-04-29 18:11
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    可能存在以下几个问题:
    1. Android使用的RSA加密算法和node端使用的RSA解密算法不匹配。
    2. 加解密过程中所用的编码方式不一致。
    3. 公钥和私钥不匹配或者损坏。 针对这些可能性可以进行以下排查:
    4. 确认Android使用的RSA加密算法和node端使用的RSA解密算法是否一致。可以打印出在进行加解密过程中所使用的算法名称或者其他算法相关信息进行对比。
    5. 确认加解密过程中所使用的编码方式是否一致。可以打印出在进行加解密过程中的编码方式进行对比。
    6. 确认公钥和私钥是否匹配或者损坏。可以尝试重新生成公钥和私钥,或者使用其他的工具对公钥和私钥进行验证。 在排查过程中可以查看各个环节的输出信息,以及错误信息进行调试。可以先在Android端使用生成的公钥对数据进行加密,然后在node端使用生成的私钥进行解密,确认是否存在问题。如果存在问题,可以打印出相应的信息进行排查。 例如,在Android端使用生成的公钥对数据进行加密的示例代码:
    public class RsaUtil {
        private static String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUdql3ySffmXK62MdQcZnLjIL5n2vcavNEt/v1U//caLzyy+olyhvdKUk/sBYNApKzEIOCy5mbm3xmGEB0HplZWCAWs/lxB+827MeSWCjEwg5/kxtMFGkqiw64gp5Bx7IqwdA3qhsFlmyxIGMm/66Ea3GCjL7PTPlDoDU5ZL803wIDAQAB";
        /**
         * 使用公钥加密
         * @param content 需要加密的密文(String类型)
         * @return base64数据
         * @throws Exception
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static String encryptByPublicKey(String content) throws Exception {
            byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr.getBytes("utf-8"));
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            byte[] plainTextBytes = content.getBytes("UTF-8");
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = cipher.doFinal(plainTextBytes);
            String encryptedBase64Str = Base64.getEncoder().encodeToString(encryptedBytes);
            System.out.println(encryptedBase64Str);
            return encryptedBase64Str;
        }
    }
    

    在node端使用生成的私钥对数据进行解密的示例代码:

    const { privateDecrypt } = require('crypto');
    const fs = require('fs');
    function decryption (data) {
      try {
        const priKey = fs.readFileSync('./pem/RsaPri.pem', 'utf8');
        const dataDecry = privateDecrypt(priKey, Buffer.from(data.toString('base64'), 'base64'));
        // 返回结果
        return JSON.stringify({
          code: 200,
          data: dataDecry
        })
      } catch (e) {
        // 返回错误
        return JSON.stringify({
          code: 500,
          data: e
        })
      }
    }
    module.exports = { decryption }
    

    在代码中可以看到Android端使用的加密算法是"RSA/ECB/PKCS1Padding",而node端使用的解密算法同样是"RSA/ECB/PKCS1Padding"。同时在加解密过程中,Android端使用的编码方式是"UTF-8",而node端也使用的是"UTF-8"。如果Android端和node端都没有问题,那么可能是公钥和私钥不匹配或者损坏,可以尝试重新生成公钥和私钥进行排查。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月29日
  • 修改了问题 4月29日
  • 创建了问题 4月29日