在go中解密一条用C#加密的消息(使用相应的公钥/私钥),我得到了一个错误。
我的客户端是用C#编写的,我的服务器是用Go编写的。我通过go的密码/rsa包(使用rsa.GenerateKey(random Reader, bits int))生成了一个私钥和公钥。然后将生成的公钥文件存储在客户端可以访问它的地方,以及服务器可以访问它的私钥文件中。我使用以下代码对客户端进行加密(使用bouncy城堡):
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-----
...页脚也是一样。我假设这是一个格式化问题,但不确定如何解决。
编辑:看起来戈朗OAEP使用的是sha256,弹性城堡使用的是SHA-1。Go的文档指定加密和解密的散列必须相同。这似乎就是问题所在?如果是,我如何更改go或C#使用的散列算法?
发布于 2020-11-14 18:06:54
是的,你需要匹配哈希。在GoLang中,如果我看一下您的代码,您已经将其设置为SHA-512。至少使用SHA-256可能是首选的,但使用SHA-1相对安全,因为MGF1函数不依赖于底层散列的冲突电阻。这也是大多数运行时的默认情况,我不知道为什么GoLang会不这么做。
最好的方法可能是为两个运行时设置SHA-512,因此这里是.NET所必需的常量。
请注意,底层的故事更加复杂,因为OAEP在标签上使用哈希,在MGF1中使用哈希(掩码生成函数1,唯一指定的)。两者都需要预先指定,并且通常使用相同的散列函数,但是使用有时不是。
标签通常是空的,大多数运行时甚至不允许设置它,因此标签上的散列值基本上是一个特定于散列函数的常量,对安全性没有影响。常量只会使事物变得不相容;“更灵活”并不总是一件好事。
https://stackoverflow.com/questions/64827603
复制相似问题