dongshaidu2456
dongshaidu2456
2018-01-11 13:39

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

  • c#
  • rsa
  • encryption

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条回答