当前位置: 首页 > 知识库问答 >
问题:

RSA在C#中加密和在Go中解密时出错

关宏毅
2023-03-14

我收到一个错误解密在C#中加密的html" target="_blank">消息(使用相应的公钥/私钥)

我的客户端是用C编写的,服务器是用Go编写的。我通过go的crypto/rsa包生成了一个私钥和公钥(使用rsa.GenerateKey(随机读取器,bits int))。然后,我将生成的公钥文件存储在客户端可以访问的地方,将私钥存储在服务器可以访问的地方。我使用以下代码(使用bouncy castle)在客户端上加密:

   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
}

解密函数抛出加密/rsa:解密错误。如果我尝试将密文直接粘贴到go中(而不是从客户端发送),则会发生相同的错误。

注意:为了加载公钥,我需要将标题从以下位置更改为:

-----BEGIN RSA PUBLIC KEY----- 
...

-----BEGIN PUBLIC KEY----- 
...

页脚也是一样。我假设这是一个格式问题,但不确定如何解决。

编辑:似乎Go语言OAEP使用sha256,而bouncy Castle使用SHA-1。Go的留档指定加密和解密的哈希必须相同。这似乎是问题所在?如果是,我如何更改go或C#使用的哈希算法?

共有1个答案

訾晋
2023-03-14

是的,您需要匹配哈希。在GoLang,如果我看一下你的代码,你已经把它设置为SHA-512了。可能最好至少使用SHA-256,但使用SHA-1相对安全,因为MGF1函数不依赖于底层哈希的抗冲突性。这也是大多数运行时的默认值,我不知道为什么GoLang决定不这么做。

最好的方法可能是为两个运行时都设置SHA-512,所以这里是. NET的必要常量。

请注意,由于OAEP使用标签上的哈希以及MGF1内的哈希(掩码生成函数1,唯一指定的一个),底层故事甚至更复杂。两者都需要提前指定,通常使用相同的哈希函数,但有时并非如此。

标签通常是空的,大多数运行时甚至不允许设置它,因此标签上的哈希值基本上是一个哈希函数特定的常数,这与安全性无关。常数只是设法使事物不相容;“更灵活”并不总是一件好事。

 类似资料:
  • 问题内容: 我有一个从Java服务器发送的公钥。在我解码并去除ASN.1标头之前,base64编码的字符串匹配。我使用将公钥存储在钥匙串中。 因此,我尝试使用公共密钥对数据进行加密,并使用Java中的私有密钥对其进行解密。我在iOS端和Java端使用。 我正在加密的是对称AES密钥,该密钥对我的实际数据进行加密,因此密钥长度为16个字节。当简单地对密钥进行base64编码时,一切正常,因此我知道此

  • 我用java加密一个单词,但用php解密时遇到了问题。 以下是我如何在android中创建密钥: 下面是我如何在android中使用生成的公钥加密单词: 然后我在android中将加密字符串转换为Bas64: 在php中,我解码base64字符串: 获取私钥: 最后,我尝试用php解密这个字符串: 我得到的错误是: 警告:openssl_private_decrypt():密钥参数不是有效的私钥.

  • 问题内容: 我正在尝试编写一个使用RSA密钥对加密和解密纯文本文件的实用程序。RSA密钥是使用ssh-keygen生成的,并照常存储在.ssh中。 我在理解如何使用Go语言crypto和crypto / rsa软件包时遇到问题吗?有关这些文档的文档很少(甚至更多,因为我对加密还不熟悉),并且示例很少。我检查了rsa_test.go文件是否有任何线索,但这只会使我更加困惑。 简而言之,我试图从.ss

  • 我有一个问题解密文本,它是在Go lang加密,使用CryptoJS。 下面是Go代码:https://play.golang.org/p/xcbl48t_in 这里是JS代码:http://jsfidle.net/ltkxm64n/ 这两种方法都能很好地加密和解密,但是当我将base64密文从GO复制到JS(或者反过来)时,它就不起作用了。我还注意到js输出的第一部分与Go输出相同,但在js输出

  • 问题内容: 我已经编写了服务器,并在中编写了客户端。他们的工作是将秘密消息从服务器发送到客户端,并使用进行加密。我正在使用库,也就是说,我使用私钥初始化对象,并使用加密消息。然后,我将此加密的消息发送到服务器,并尝试使用库 使用相同的私钥对其 进行 解密。问题是它无法正确解密。它总是输出128位长的消息,其中秘密消息被随机放置在其中,通常应返回just 。 问题答案: 问题是关于填充。Python

  • 问题内容: PHP 5.3是否有任何类可提供RSA加密/解密而无需填充? 我有私钥和公钥,p,q和模数。 问题答案: 您可以使用phpseclib,这是一个纯PHP RSA实现: