【问题标题】:Send RSA Public Key in Java to PHP server将 Java 中的 RSA 公钥发送到 PHP 服务器
【发布时间】:2015-03-02 11:57:01
【问题描述】:

我在尝试将 Java 生成的 RSA 公钥转换为字符串格式时遇到了麻烦,因此我可以在 PHP 端使用它。我尝试将其转换为字符串,但在 PHP 端加密失败。我像这样在 Java 中生成一个公钥:

KeyPairGenerator k = KeyPairGenerator.getInstance("RSA");
k.initialize(1024);
KeyPair kp = k.genKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();

输出到 String 时的 PublicKey 如下所示:

RSA Public Key
    modulus: eded852d98899fd083b6b989cbdbb41c0cf604ccdc3c4b46a6e3bdf92be898db1c53133dba4fcbc3bd7e8934b7b212856146169858ef2177e9c04c995d4fb61f9957eb6ff61a1183de03e5459ecbae7d1196778be844127fd7e80668b57037cab7a3e56c02cb881c3fb2aaddd47e5cae49c14582be01722cfa5352d9bdc97a37
    public exponent: 10001

然后我像这样对这个 PublicKey 进行编码:

byte[] pKbytes = Base64.encode(publicKey.getEncoded(), 0);
        String pK = new String(pKbytes);
        String pubKey = "-----BEGIN PUBLIC KEY-----\n" + pK + "-----END PUBLIC KEY-----\n";

输出看起来像这样:

-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDt7YUtmImf0
    IO2uYnL27QcDPYEzNw8S0am4735
    K+iY2xxTEz26T8vDvX6JNLeyEoVhRhaYWO8hd+nATJldT7Yf
    mVfrb/YaEYPeA+VFnsuufRGWd4vo
    RBJ/1+gGaLVwN8q3o+VsAsuIHD+yqt3UflyuScFFgr4Bciz
    6U1LZvcl6NwIDAQAB
    -----END PUBLIC KEY-----

这看起来类似于我在 PHP 端的格式。使用 Base64 对其进行编码给出了我打算用于键字符串的最终格式。

LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1NSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURD
 QmlRS0JnUUR0N1lVdG1JbWYwSU8ydVluTDI3UWNEUFlFek53OFMwYW00NzM1SytpWTJ4eFRFejI2
    VDh2RHZYNkpOTGV5RW9WaFJoYVlXTzhoZCtuQVRKbGRUN1lmbVZmcmIvWWFFWVBlQStWRm5zdXVm
    UkdXZDR2b1JCSi8xK2dHYUxWd044cTNvK1ZzQXN1SUhEK3lxdDNVZmx5dVNjRkZncjRCY2l6NlUx
    TFp2Y2w2TndJREFRQUItLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0=

在这一切之后,钥匙似乎不起作用。它使用我发送的密钥对消息进行加密,但是当我将其发送回 Java/Android 应用程序(其中包含私钥)时,它无法解密它。我已经能够做到这一点,反之亦然(即从 PHP 中获取编码的密钥字符串并将其转换为供 Java/Android 应用程序使用的公钥)我在这里做错了什么吗?我的直觉告诉我我向 PHP 服务器发送了错误的字符串

Java 中的堆栈跟踪如下所示:

03-02 12:02:26.170  W/System.err﹕ java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
03-02 12:02:26.182  W/System.err﹕ at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(CipherSpi.java:464)
03-02 12:02:26.186  W/System.err﹕ at javax.crypto.Cipher.doFinal(Cipher.java:1204)
03-02 12:02:26.186  W/System.err﹕ at com.app.test.NQ.NQCrypto.decrypt(NQCrypto.java:116)

这是我尝试用 Java 解密数据的方法:

public static String decrypt(String data) throws Exception {

        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", "BC");

        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // Base 64 encode the encrypted data
        byte[] encryptedBytes = Base64.encode(cipher.doFinal(data.getBytes()), 0);

        return new String(encryptedBytes);

    }

【问题讨论】:

  • @Duncan 它使用我发送的密钥对消息进行加密,但是当我将其发送回 Java/Android 应用程序(包含私钥)时,它无法解密它
  • @Daniel 你在 Java 中遇到了什么错误?
  • @Daniel 这是异常消息吗?如果是这样,异常是什么类型 - 发布堆栈跟踪。
  • @Duncan 抱歉不是空的。发布堆栈跟踪

标签: php android encryption rsa phpseclib


【解决方案1】:

你的解密代码看起来不对:

cipher.doFinal(data.getBytes())

您的data 变量是一个字符串,但字符串不能保存原始加密数据而不破坏它。除非您的密文实际上是十六进制编码或 base64 编码等。在这种情况下,getBytes() 不是将其解码为字节数组的正确方法。

所以要么修正你发送密文的方式,要么修正你将密文解码为字节数组的方式。

【讨论】:

  • 你是救生员!不完全是正确的答案,但问题就在那条线上。我必须对字符串变量数据进行 base64_decode。
  • @Daniel 好吧,那我在回答中建议的...“或者更正您将密文解码为字节数组的方式 " :-)
猜你喜欢
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 2018-12-22
相关资源
最近更新 更多