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

在用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 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发