加解密算法二:非对称加解密及RSA算法的实现
加密和解密使用不同的密钥的一类加密算法。这类加密算法通常有两个密钥A和B,使用密钥A加密数据得到的密文,只有密钥B可以进行解密操作(即使密钥A也无法解密);
相反,使用密钥B加密数据得到的密文,只有密钥A可以解密。这两个密钥分别称为私钥和公钥。私钥就是你个人保留,不能公开的密钥,而公钥则是公开给加解密操作的另一方的。
根据不同用途,对数据进行加密所使用的密钥也不相同(有时用公钥加密,私钥解密;有时相反用私钥加密,公钥解密)。非对称加密的代表算法是RSA算法。
RSA算法是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。它的安全性是基于大整数素因子分解的困难性,而大整数因子分解问题是数学上的著名难题,至今没有有效的方法予以解决,因此可以确保RSA算法的安全性。
公钥和私钥的产生:
public static void CreatePublicAndPrivateKey(out string publicKey, out string privateKey) { //声明一个RSA算法的实例,由RSACryptoServiceProvider类型的构造函数指定了密钥长度为1024位 RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024); //实例化RSACryptoServiceProvider后,RSACryptoServiceProvider会自动生成密钥信息 publicKey = rsaProvider.ToXmlString(false); privateKey = rsaProvider.ToXmlString(true); }
公钥加密,私钥解密:
public static string RSAEncryptWithPublicKey(string source, string publicKey) { if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(publicKey)) { return ""; } else { try { byte[] data = Encoding.Default.GetBytes(source); RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024); //将公钥导入到RSA对象中,准备加密 rsaProvider.FromXmlString(publicKey); int keySize = rsaProvider.KeySize / 8; int bufferSize = keySize - 11; byte[] buffer = new byte[bufferSize]; MemoryStream msInput = new MemoryStream(data); MemoryStream msOuput = new MemoryStream(); int readLen = msInput.Read(buffer, 0, bufferSize); while (readLen > 0) { byte[] dataToEnc = new byte[readLen]; Array.Copy(buffer, 0, dataToEnc, 0, readLen); byte[] encData = rsaProvider.Encrypt(dataToEnc, false);//加密 msOuput.Write(encData, 0, encData.Length); readLen = msInput.Read(buffer, 0, bufferSize); } msInput.Close(); byte[] result = msOuput.ToArray();//得到加密结果 msOuput.Close(); rsaProvider.Clear(); return Convert.ToBase64String(result); } catch (Exception ex) { return ex.Message; } } } public static string RSADecryptWithPrivateKey(string source, string privateKey) { if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(privateKey)) { return ""; } else { try { byte[] data = Convert.FromBase64String(source); //byte[] data = Encoding.Default.GetBytes(source); RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024); //将私钥导入RSA中,准备解密 rsaProvider.FromXmlString(privateKey); int keySize = rsaProvider.KeySize / 8; byte[] buffer = new byte[keySize]; MemoryStream msInput = new MemoryStream(data); MemoryStream msOuput = new MemoryStream(); int readLen = msInput.Read(buffer, 0, keySize); while (readLen > 0) { byte[] dataToDec = new byte[readLen]; Array.Copy(buffer, 0, dataToDec, 0, readLen); byte[] decData = rsaProvider.Decrypt(dataToDec, false);//解密 msOuput.Write(decData, 0, decData.Length); readLen = msInput.Read(buffer, 0, keySize); } msInput.Close(); byte[] result = msOuput.ToArray();//得到解密结果 msOuput.Close(); rsaProvider.Clear(); return Encoding.Default.GetString(result); } catch (Exception ex) { return ex.Message; } } }