dongshaidu2456 2018-01-11 13:39
浏览 371
已采纳

在用GO语言加密的同时,如何在c#中解密RSA加密的字符串。 解码OAEP填充时发生错误

I have an application running on c# and another server application in go. I need to implement secure communication using rsa.
What i'am doing is I've initialized the RSA provider in my C# application and generated public key to extract Modulus and Exponent. Then concatenated the modulus (Hexadecimal) and exponent (int) and converted this string to Base64 string, send it to a GO endpoint.

Here is C# code snippet

public string ConvertToPublicKey()
    {
        CspParameters rsaParameters = GetCspParameters();
        RSACryptoServiceProvider provider = newRSACryptoServiceProvider(rsaParameters);
        string paramsXml = RsaProvider.ToXmlString(false);

        XDocument xDocument = XDocument.Parse(paramsXml);
        string modulus = xDocument.Descendants().FirstOrDefault(x => x.Name == "Modulus")?.Value ?? string.Empty;
        string exponent = xDocument.Descendants().FirstOrDefault(x => x.Name == "Exponent")?.Value ?? string.Empty;
        byte[] base64BytesOfModulus = Convert.FromBase64String(modulus);
        string hexaDecimalofModulus = BitConverter.ToString(base64BytesOfModulus).Replace("-", string.Empty);
        byte[] base64BytesOfExponent = Convert.FromBase64String(exponent);
        string hexadecimalOfExponent = BitConverter.ToString(base64BytesOfExponent).Replace("-", string.Empty);
        int intOfExponent = Convert.ToInt32(hexadecimalOfExponent, 16);
        byte[] publicKey = Encoding.UTF8.GetBytes($"{hexaDecimalofModulus};{intOfExponent}");
        return Convert.ToBase64String(publicKey);
    }

    private static CspParameters GetCspParameters()
    {
        const string containerName = "KeyContainer";
        return new CspParameters
        {
            KeyContainerName = containerName,
            Flags = CspProviderFlags.UseMachineKeyStore
        };
    }

At Go endpoint I received public key and modulus correctly. Then I encrypted the message using public key and sent it back to c# application in response after converting encrypted message byte[] to base64.

Here is GO code snippet

func GetLicenseInfo(responseWriter http.ResponseWriter,request*http.Request) 
    {
    encryptionKey := request.Header.Get("Authorization")
    var decodedStringBytes, errors = b64.StdEncoding.DecodeString(encryptionKey)
    if errors == nil {
        var decodedString = string(decodedStringBytes)
        result := strings.Split(decodedString, ";")
        modulus := new(big.Int)
        modulus.SetString(result[0], 16)
        exponent, exponentErrors := strconv.Atoi(result[1])
        if exponentErrors == nil {
            var someInfo = utils.GetInfo()
            var InfoInJson = ToJson(someInfo)
            publicKey := &rsa.PublicKey{N: modulus, E: exponent}
            var encryptedMessage, err = rsa.EncryptOAEP(sha256.New(),rand.Reader, publicKey,[]byte(InfoInJson), []byte(""))
            var response = b64.StdEncoding.EncodeToString(encryptedMessage)
            if err == nil {
                json.NewEncoder(responseWriter).Encode(response)
            }
        }

    }
}

func ToJson(model InfoModel) string {
    InfoInJson, errors := json.Marshal(model)
    if errors != nil {
        panic("An error occurred while serializing the response")
    }
    return string(InfoInJson)
}

When i received the response back in Base64 string i converted it to Byte[] and tried decrypting that with same instance of RSACryptoServiceProvider then it throws the following exception

Error occurred while decoding OAEP padding.

any help?

UPDATE for example here is the base64 string that i received in GO

QUQ2NDlFRTlCQTA3Q0IxNEI1MTNDMzczQzBBMjNBOEQyMDI5MkVGQTBFMjgyNUIyMEEyMzM1MEE3OTUyNjgyQ0Y3MEFBQjJBMTZGMzQyNTM4MkU2RDZBRjU5M0IxRTI2MTE0OEIyQkFFRTY3MUVDMTQ1NDk1NjBDRkNEQUNCQzI3RUUxNDRFODZDQUI4RDBDOUY2OENBNTUwNUMxQjZGQkVBQjQ0MTlBMjg3RDhBRjgxRDUyREY3MEM0RDZDQTA5MkREMzk5Q0NEODU5Q0FGQzAzQ0JEQ0JBQzgwOTg3NDY0NThBMkY4NEREOTc1QjU5QTJBMUNBNzQxQTBDNkQ2RDs2NTUzNw==

and here is what my GO app sent back

QuWpWdEPSJR+l9UJTkh+heJJ/NpPwhz/hVVu1VdKYdz37YGWWdKTj7Fc5lZ3A8p1WjtC4F+yieZCz0tEatCqTpRmm9g6Oioyjbtr9qGTxO/PE+GA33YyBe6nmMRe674SPePx/fg6l3nnfSZ4/+iLCV4bNgyNqFHCaXc7H4Snms8=

UPDATE 2 I've updated the code snippet and included the data types and here is the part that dscrypts the content received from GO end point

public byte[] Decrypt(byte[] encryptedData, RSAParameters rsaParameters)
    {
        RsaProvider.ImportParameters(rsaParameters);
        return RsaProvider.Decrypt(encryptedData, true);
    }

i receive a base64 string then i convert to byte[] using this

byte[] b = Convert.FromBase64String(responseString); byte[] decryptedBytes=crypto.Decrypt(b, crypto.RsaProvider.ExportParameters(false));

crypto is the instance of the class that contains decryption logic,instacne of RSACryptoServiceProvider and that method(ConvertToPublicKey) given above returning the public key

  • 写回答

2条回答 默认 最新

  • dongzhuo1880 2018-01-11 21:23
    关注

    After addressing comments by @bartonjs I've also changed response response from go to

    var encryptedMessage, err = rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, []byte(licenseInformationJson), []byte(""))
    if err == nil {
        responseWriter.Write([]byte(encryptedMessage))
    }
    

    Notice []byte(encryptedMessage) byte stream sent from go to c# is slightly changed because encryptedMessage is []unint8. so you need to typecast encryptedMessage to []byte so that values are correctly mapped in c#.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:matlab里这个代码报了‘位置 1 处的索引超出数组边界(不能超出 1)
  • ¥15 maccms影视模板 制作影视网站失败 求
  • ¥15 stm32按键设置闹钟数进退位不正常
  • ¥15 三电平逆变器中点电位平衡问题
  • ¥20 这怎么写啊 java课设
  • ¥15 用C语言完成一个复杂的游戏
  • ¥15 如何批量更改很多个文件夹里的文件名中包含文件夹名?
  • ¥50 MTK手机模拟HID鼠标出现卡顿
  • ¥20 求下下面这个数据结构代码
  • ¥20 前端 二进制文件流图片转化异常