我有一个用go编写的gRPC服务器,它为用java编写的客户端提供公钥。密钥使用带有sha-256的OAEP填充,并以我认为的PEM格式作为ByteString接收。
我试图读取收到的字节并将它们放入用于解密的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
当我执行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对象
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){}
这会导致“非法base64字符”。我假设这与密钥使用OAEP填充的事实有关。但是,当我将密钥工厂/密码的实例更改为“RSA / ECB / OAEPWITHSHA-256ANDMGF1PADDING”时,我收到此错误:
java.security.NoSuchAlgorithmException: RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING KeyFactory not available
答案 0 :(得分:2)
不同的base64解码器在遇到非法base64字符时是否抛出异常或是否只是忽略该字符时有不同的规则。包含换行符的空格不是有效的base64字符。要纠正错误,您必须在base64解码之前从PEM公钥字符串中删除换行符。
key = key.replace("-----BEGIN RSA PUBLIC KEY-----\n", "");
key = key.replace("-----END RSA PUBLIC KEY-----", "");
// add the following line
key = key.replace("\n", "");
注意:这是过于简单的,因为它假定'\ n'将是行分隔符。您还可以将替换添加到其他公共行分隔符字符序列。确保按长度订购替换件,首先是最长的,最后一个是最短的。