如何从接收为字节字符串的密钥创建 java.security.publicKey - OAEP 填充

How to create java.security.publicKey from a Key recived as a ByteString - OAEP Padding

我有一个用 go 编写的 gRPC 服务器,它为用 java 编写的客户端提供 public 密钥。密钥使用带有 sha-256 的 OAEP 填充,并以我认为是 PEM 格式的字节字符串形式接收。

我正在尝试读取接收到的字节并将它们放入用于解密的 PublicKey 对象中

转到服务器代码段:

plaintext, err := rsa.DecryptOAEP(sha256.New(), rng, d.decKey, ciphertext, label)
if err != nil {
    log.Fatalf("Error from decryption: %s\n", err)
}

// H := H'
return plaintext

RSA 密钥

这是我执行 client.getKey().toString()

时打印到控制台的密钥
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5SuTn/IhVfLpcgEtbkty
ip6ajx8tcVNt862lj24cz/zGEqzD3sDaRaS+9l16l63T/mWutPqyCBWekg9oGK6Z
ni313nJyvMETCY1kc9mj7IB9yNd00eXr+jYJNF92qc3k0IlyxDjD6hE/InlKn1cM
njYOMYhZtsMSQQElIeYsiqOD1k55E4905XP8gh3K5YT8jVBHJHboJiXVqBJ0CQPq
LKYufey+WcX3p5wKKUgycKxB1zgS1BAHJ/l9x6fxDTE85CBIeRyfSXijHgiWGAEY
MDOIRIBpA8MT5q0Mghy9+KryIHNkc+659DAgCjghY8pmyFezF5gDzRpEi+jB5OOT
bQIDAQAB
-----END RSA PUBLIC KEY-----

我一直在尝试将其解析为字符串,去掉“-----BEGIN RSA PUBLIC KEY-----”和“-----END RSA PUBLIC KEY-----" 并将剩余的字符串转换为字节数组,然后转换为 PublicKey 对象

Java代码

String key = client.getPublicKey(nonce).getRSAEncryptionKey().toString();
key = key.replace("-----BEGIN RSA PUBLIC KEY-----\n", "");
key = key.replace("-----END RSA PUBLIC KEY-----", "");
byte[] keyBytes = Base64.getDecoder().decode(key); //bytes of key
Cipher cipher_RSA;
        try {
            cipher_RSA = Cipher.getInstance("RSA");
            X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey pk = keyFactory.generatePublic( spec);

            cipher_RSA.init(Cipher.ENCRYPT_MODE, pk); 
            return cipher_RSA.doFinal(message);
        }catch(Exception e){}

这一直导致 "Illegal base64 character"。我认为这与密钥使用 OAEP 填充这一事实有关。但是,当我将键 factory/cipher 的实例更改为 "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" 时,我收到此错误:

java.security.NoSuchAlgorithmException: RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING KeyFactory not available

不同的base64解码器对于遇到非法base64字符是抛出异常还是直接忽略该字符有不同的规则。白色 space,包括换行符,不是有效的 base64 字符。要更正您的错误,您必须在 base64 解码之前简单地从 PEM public 密钥字符串中删除换行符。

key = key.replace("-----BEGIN RSA PUBLIC KEY-----\n", "");
key = key.replace("-----END RSA PUBLIC KEY-----", "");
// add the following line  
key = key.replace("\n", "");

注意:这是过于简单化了,因为它假定“\n”将是行分隔符。您还可以将替换添加到其他常见的行分隔符字符序列。确保按长度订购替换品,最长的在前,最短的在后。