【发布时间】:2021-02-25 20:33:03
【问题描述】:
我在解密用 C# 加密的 go 消息时出错(使用相应的公钥/私钥)
我的客户端是用 C# 编写的,而我的服务器是用 Go 编写的。我通过 go 的 crypto/rsa 包(使用rsa.GenerateKey(random Reader, bits int))生成了一个私钥和公钥。然后,我将生成的公钥文件存储在客户端可以访问的位置,并将私钥存储在服务器可以访问的位置。我使用以下代码在客户端上加密(使用充气城堡):
public static string Encrypt(string plainText)
{
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
PemReader pr = new PemReader(
new StringReader(m_publicKey)
);
RsaKeyParameters keys = (RsaKeyParameters)pr.ReadObject();
// PKCS1 OAEP paddings
OaepEncoding eng = new OaepEncoding(new RsaEngine());
eng.Init(true, keys);
int length = plainTextBytes.Length;
int blockSize = eng.GetInputBlockSize();
List<byte> cipherTextBytes = new List<byte>();
for (int chunkPosition = 0; chunkPosition < length; chunkPosition += blockSize)
{
int chunkSize = Math.Min(blockSize, length - chunkPosition);
cipherTextBytes.AddRange(eng.ProcessBlock(
plainTextBytes, chunkPosition, chunkSize
));
}
return Convert.ToBase64String(cipherTextBytes.ToArray());
}
go服务器从头部解析这个字符串,使用私钥解密:
func DecryptWithPrivateKey(ciphertext []byte, priv *rsa.PrivateKey) []byte {
hash := sha512.New()
plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
}
return plaintext
}
解密函数抛出crypto/rsa: decryption error。如果我尝试将密文直接粘贴到 go 中(而不是从客户端发送),则会发生同样的错误。
注意:为了获取要加载的公钥,我需要更改标题:
-----BEGIN RSA PUBLIC KEY-----
...
到
-----BEGIN PUBLIC KEY-----
...
页脚也是如此。我假设这是一个格式问题,但不确定如何解决。
编辑:似乎 golang OAEP 使用 sha256 而充气城堡使用 SHA-1。 Go 的文档规定加密和解密的哈希值必须相同。这似乎是问题所在?如果是,如何更改 go 或 C# 使用的哈希算法?
【问题讨论】:
-
我尝试在 go 中使用更改后的头作为公钥,并且它工作(能够加密和解密),所以不是这样。
-
我还尝试将原始字节值粘贴到 go 中,但仍然无法正常工作。所以也不是这样。
-
另外,你忘了解码base64
标签: c# go encryption rsa bouncycastle