/// <summary> /// RSA注冊碼生成驗證幫助類 /// </summary> public class RSASignature { /// <summary> /// 生成密匙 /// </summary> /// <param name="privateKey">私匙</param> /// <param name="publicKey">公匙></param> public static void GenerateKeys(out string privateKey, out string publicKey) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { privateKey = rsa.ToXmlString(true); publicKey = rsa.ToXmlString(false); } } /// <summary> /// RSA簽名 /// </summary> /// <param name="sSource" >明文</param> /// <param name="sPrivateKey" >私匙</param> /// <returns>密文</returns> public static string CreateSignature(string sSource, string sPrivateKey) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(sPrivateKey); RSAPKCS1SignatureFormatter sf = new RSAPKCS1SignatureFormatter(rsa); sf.SetHashAlgorithm("SHA256"); byte[] source = System.Text.ASCIIEncoding.ASCII.GetBytes(sSource); SHA256Managed sha2 = new SHA256Managed(); byte[] result = sha2.ComputeHash(source); byte[] signature = sf.CreateSignature(result); return Convert.ToBase64String(signature); } } /// <summary> /// RSA簽名驗證 /// </summary> /// <param name="sEncryptSource">密文</param> /// <param name="sCompareString">需要比較的明文字符串</param> /// <param name="sPublicKey">公匙</param> /// <returns>是否相同</returns> public static bool VerifySignature(string sEncryptSource, string sCompareString, string sPublicKey) { try { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(sPublicKey); RSAPKCS1SignatureDeformatter df = new RSAPKCS1SignatureDeformatter(rsa); df.SetHashAlgorithm("SHA256"); byte[] signature = Convert.FromBase64String(sEncryptSource); SHA256Managed sha2 = new SHA256Managed(); byte[] compareByte = sha2.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sCompareString)); return df.VerifySignature(compareByte, signature); } } catch (Exception) { return false; } } }
改進:將SHA1改為SHA256,提高安全性
測試
string publicKey = "<RSAKeyValue><Modulus>2DF7PLozXLLJb2vTknucTOK8+ucjYlVFOThnRwqULjeSuA2ZlReaBVXRy8PonVkXXfN2tjosy2ToTwHNX4UQP5kkEbBWYk8knOZPF/96OI2GfjGYnwNUT0CIKHda8B8ztfh1LQanNOCrrByHIuGTORL1WR2hlbaIHRrOIRkeOMc=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; string privateKey = "<RSAKeyValue><Modulus>2DF7PLozXLLJb2vTknucTOK8+ucjYlVFOThnRwqULjeSuA2ZlReaBVXRy8PonVkXXfN2tjosy2ToTwHNX4UQP5kkEbBWYk8knOZPF/96OI2GfjGYnwNUT0CIKHda8B8ztfh1LQanNOCrrByHIuGTORL1WR2hlbaIHRrOIRkeOMc=</Modulus><Exponent>AQAB</Exponent><P>+WLUzPp7LeMmXaZ3Ebcw6+Ks1HA6XlkpfhLS4DOnViw2O1V/8EXFO77KwFLSwlCzfXo1LN0JuTEsacGdU3f5yw==</P><Q>3e1K+J8Ns4UrbhQzgIbyGf8JX+VaETWClJSq9vEXelHGfG9/+5bbGvnF4Wo1c/Kdkuz5IQHfYbuTgMU4LpVNdQ==</Q><DP>bV/6IrhMo/B22CX1HNDyZNIyqK1b/BswxnltASXGY1XapyU1imSfPzfLZpQsmUqZnhOmFLoQ1KcLaoqe/IenBw==</DP><DQ>J3CndT3XEoNlL3/5kyroVcRkZx18fzhyR3OQWqiIEp3711t9dDngIJApIaFddIi2hkkFEV+i0lyinyztiiHQjQ==</DQ><InverseQ>Fdk/2JOc/gj7YKsKgMEEVC0+X+WlAMhF+PJVgs188vIQSuXJTRi8Z4A214fvX49s2G81Th7KdYUWCvBAeD153Q==</InverseQ><D>wgJFkY2XIgzfb7nXt5BuByFCbfaWblwPLvZK2BnKOF9urvSlaoIvmbIV/0HjsbCNo6YkVguGv0/imWQIpTuIA6O5S1NX/dbYLp2/rSNl0/xSB5ZjX06VAYbeIsB7YWw87+35K8DrIrlZDMP4Mk6h+pawdgLTtIo/tjTpBhCfB+E=</D></RSAKeyValue>"; private void btnCreateRegister_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txtComputerInfo.Text)) { txtRegister.Text = RSASignature.CreateSignature(txtComputerInfo.Text.Trim(), privateKey); } else { MessageBox.Show("請輸入機器碼!"); txtComputerInfo.Focus(); } } private void button1_Click(object sender, EventArgs e) { bool result = RSASignature.VerifySignature(txtRegister.Text, txtComputerInfo.Text.Trim(), publicKey); MessageBox.Show(result.ToString()); }