I am trying to use the .Net RSA functions to sign a Hash, but when i try to Sign the hash and then verify the Signed string it turns out false. This can be reproduced by running the DoTest()
Function.
Any help would be appreciated.
using System;
using System.Text;
using System.Security.Cryptography;
namespace Crypto
{
public static class Signing
{
public static string Sign(string Hash)
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString("<RSAKeyValue><Modulus>pnjojEb82qGpB4/AkI3ydcF1L9cy33u1bT2dFoU5FlVQWUOYunl11M3cjsYSm/cpM6qjh0oQcaqdRUrUGK4NLiBypPCYlxRym+ZYh2TSeEWZSMxxmdxcWVQo2fZji7sq38XB2inB4WoogYwX4a+4Jenj1lzcrs+08uqSgExRIQOEi2DldQLGo5P9IocptlYCDRN5qR0ARVlpxvFMmC/rcoKS2g1RZLz+rbLOaIFFQY4PE3TL4CLe2dmc/WmD0w6CsjY4Q9EiCwn+FUqPzm9Vo539l3n7y25Db18E4kxHOlGq0iFv5MeXEqWn51Fst9aZnq9AvDJqh/hDIShJ2HqnwxpN4a2LZp5mGbauyX5KtHa5G87I0ExZf4cX08Nn44KeQ8l3ouAnes+BhsuXt12ijQPycxgCMt9Mn6MjOnSa1oATouiefz131Rj3OBmVQku6p8q4pAy9ALmxn+28m7A1KJrRNGDXNJAOFeyueukhg+VJiRAGSeAoanm5ykmaDOE0clBQxTYcrTpKI/6xrlNglJi1v1Z9ZitxzmaAN7ZJBJ/elm1hr8KEGRMxtt8xCpzE1+2rMiHlD9qMn42H2N72YQam81UtGarLMzkY/egS6ds7rx3ccB+HFpPVJan/+pIvCbRpuaNcWIX8wjhaWS0IKSTP6Y7vzNebZVdr0+TQ18U=</Modulus><Exponent>AQAB</Exponent><P>wJjH5cYFiOYIz/9IENUiZ/F6TkE0jq2l8JpXk2dGKvzqlOO93i6pJ2rRUdugLRiqzSOt+yE2Jpxued6gumzqvsy0q5HLTqY1n0eLVOfkn4x8tRvMAVbW185duBkgHLuLAzkJqnAd8CXpkca4M7mvWi4EDpiPoSJjeZt0kSkaRzjOSEp4Q5WZUhN5gRM7mn2VQSawFIJtNxAJLuneEc03D8O41+9KVQ8sS7AIVZdu6ortvBveU8e7HA/CNIutyFcdtgoCu4XUQSlAQQD75qlfSJvPT7rvxUsc53FKAIcQNz28g4Zy8/2K8B7T6SChsalUNcbiDuQcBtzAEBDkDlO8Fw==</P><Q>3UZ35kUnAbj/IY/kSsOsMwWjw0djKnY+Yt22vcN4FImhMyMTKKnpCbX+XFQpK6Gh8Gv4lVjgeDi+fb6AbzDFff2fEGwmVyI4EkRa50KdTQKwCZrxwpljngl3M06vTXzjV1L9IcBXQt3so7HA4YJ4kY8woadgz/41+dij6Nlz4bAn+VA8QIbjR0x9rOR/FxM0cCsTqNYsDUxmyqwPlqWdA73KoAFyjGg12fij3BKZdT3AnGeOZUp4Ukb/Xapaj8E8jIAtl1/p9uVEj6gZqcSkBhj1IE+zJ54iS7u8Ijd8SBcLbfsJ+12FXCT/zFsTJ+UUro+dQYKzUe05WMN5Eowogw==</Q><DP>A1LfqER5lfo6TrSeHsQ+2sJdFPqlGI1Ant1bA401tco1lioz/aCahLagNCRxKDYTxISIHRxend33Ph0scussReysdYWHl6zgogYPDoEN/f7jrBB1vdQs0v6ZuXKdjkFiTcTvOMTEj39n/38JcMMUlp7SrRnO6L36L4ASS+sErBP74119o9TyF2uEnkihr7HZII21XjU+A0RAlFGu5mm/OINtLjTP+JXRcuDv0+JQJLYPEj784D9DKGHRPSzn69wtBBY6I9hUaGd412ZX8owbu9oMgti8CJCaSBg5abbq/bkQBskMNM+8VRaDG7PXdoRwkpkDD7S6Exg+LEjOVrz1Mw==</DP><DQ>2mYMP6Zvep7KiqjIThbVpsJhQYP7V9S/fLuS+7erlLHG/n8XEOKrVV9hAGY9AIiXGoKnJ1lCrMZtFhVqFNURiGpEjmQAb64ho7397xXrxi/p6oEZL9ZP4ZM8KNL36cZjaTRLDf4W4rPCNktisfIh6KFpAZT/1Cr3wXNXTKMcYlyJB+Vuos3AFAZmYLhizDazYibST6mcbz/CkTXEaQ9ra17vWIA1PGo7BLoJmVRuTK63pmf7vvQC0EqtEBjtK8gxaAe3eBo+BeeChTwIoGyq7C3D+7FOhcLp3NAeP7N+InVEXbgSwRwsXadTJrOZs53CjQzIzPkg3rMDEB5XKLxX2w==</DQ><InverseQ>srv0aCRx+dycT8mBMxGemXBal88+lPDd4l1okp1CY0Lv7lL2AojYQvQT3Ks8AuSzLyWuZ8sQl2JD/QsluZSbvWLb/RMW/h64DbM3ei108krbu5EHPWyGDdJSTtDR0XtNouQBCS4D1rc8M2psexexpIr/8uQG93I2h3hAddQ4SSspQs3oV4PMSVwFQLsxTaxVMi+F+Enu2W5a98+MPCQGoZcwatu3gow+2lFFAe2lTcSiEZdJEUbyxWG6sgh1iBv0gypN3Bny06peK1gZLd+IAyjpYyl9JCPZqWXxvcaJUtduR/JGA8NypCs+QBNwse2d4ipJVxhn756EOavOR/GYHg==</InverseQ><D>dRWpCbCL+wGkrurOV11e4K+WSnWjFEggDJs/Ny2wPyL2BjJi4xS2aVv4+noZcJTf57TmmyrecfO79ZZxooIYRw8PUy7dQ7Vf/oJ+VYv19B2PeAJDDCJO2Y01xkdjME4OE6E1fMnN0Usm/iaYTWWXsSLV2lkp5dG0xP1y2MXUcdHVkWovOKMhLr/RVE2YauQHQUcnVGhPXndKzF++rXNWuA1aV/7x9lZvEaAnSJ1TJo5R0C9fjV85OiOyJRHnY7Ra/BjibeBTf0wh5ruwdVMc+p0OVVG4ZRZCW7yK5NcdackyyeQ2nMQ8XyMf+rPsMUjAdzlv4G3dO5DDNjjt51ItVwq7jSPbWf27D6aDW7OhR7fOszY+SwxOscAXaXm1w9VygzqQLSgYNcfe4ivOgzv0VfCrYIsakjRNTtuQz41Mi3LbxtHugmfjOGkmtEd046SMIlkJpPwi+neSYRRcq+e1nxHBFhPtS76WjMXBOHveX1ge+OD70r8i0kMFFdCaDsh0XubB6vAm7gzfZ3HOt6phSaaBTd4iYfNNtkIIbtlYgoDWnZT/QfRDSw26S0ZNJKfb+ysq88+MLvf00xIGMxIIat3YFNgvdAQ47LoLq3CpTHYeFkT2wMoO9gLHfJVW0aJ027fIO5mnJTNj/G0TRqRnh25RdwZQt2pQxQbkhOW/PGk=</D></RSAKeyValue>");
byte[] SignedHashValue = RSA.SignHash(HashBytes(Hash),"SHA512");
return (Convert.ToBase64String(SignedHashValue));
}
public static bool Verify(string signature, string Hash)
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString("<RSAKeyValue><Modulus>pnjojEb82qGpB4/AkI3ydcF1L9cy33u1bT2dFoU5FlVQWUOYunl11M3cjsYSm/cpM6qjh0oQcaqdRUrUGK4NLiBypPCYlxRym+ZYh2TSeEWZSMxxmdxcWVQo2fZji7sq38XB2inB4WoogYwX4a+4Jenj1lzcrs+08uqSgExRIQOEi2DldQLGo5P9IocptlYCDRN5qR0ARVlpxvFMmC/rcoKS2g1RZLz+rbLOaIFFQY4PE3TL4CLe2dmc/WmD0w6CsjY4Q9EiCwn+FUqPzm9Vo539l3n7y25Db18E4kxHOlGq0iFv5MeXEqWn51Fst9aZnq9AvDJqh/hDIShJ2HqnwxpN4a2LZp5mGbauyX5KtHa5G87I0ExZf4cX08Nn44KeQ8l3ouAnes+BhsuXt12ijQPycxgCMt9Mn6MjOnSa1oATouiefz131Rj3OBmVQku6p8q4pAy9ALmxn+28m7A1KJrRNGDXNJAOFeyueukhg+VJiRAGSeAoanm5ykmaDOE0clBQxTYcrTpKI/6xrlNglJi1v1Z9ZitxzmaAN7ZJBJ/elm1hr8KEGRMxtt8xCpzE1+2rMiHlD9qMn42H2N72YQam81UtGarLMzkY/egS6ds7rx3ccB+HFpPVJan/+pIvCbRpuaNcWIX8wjhaWS0IKSTP6Y7vzNebZVdr0+TQ18U=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>");
bool verified = RSA.VerifyData(HashBytes(Hash),"SHA512", Convert.FromBase64String(signature));
return verified;
}
public static byte[] HashBytes(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
public static void DoTest()
{
string hash = "878AE65A92E86CAC011A570D4C30A7EAEC442B85CE8ECA0C2952B5E3CC0628C2E79D889AD4D5C7C626986D452DD86374B6FFAA7CD8B67665BEF2289A5C70B0A1";
string signed = Sign(hash);
bool Verified = Verify(signed, hash);
Console.WriteLine(Verified);
}
}
}
You shouldn't use the RSAPKCS1SignatureFormatter
class, when you try to verify a hash with the RSACryptoServiceProvider.VerifyData()
method. The signature must come from the RSACryptoServiceProvider.SignData()
method, as stated in the documentation of RSACryptoServiceProvider.VerifyData()
:
Remarks
This method verifies the RSA digital signature produced by the
SignData
method. [...]
Use the SignData()
method to sign the data and use the VerifyData()
method to check the signature.