RSA加密
加密原理
RSA加密演算法:http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
用实例给新手讲解RSA加密算法:http://www.cfca.com.cn/zhishi/wz-012.htm
应用
java程序使用生成一个RSA生成一对秘钥,Net程序要使用私钥对消息签名,发送给Java端。
怎么在net中读取PKCS#8 私钥并签名?
最简单使用外部组件
如System.Security.Cryptography, BouncyCastle, OpenSSL.Net and Chilkat RSA
用Security.Cryptography ,需要net3.5以上的框架
byte[] dataToSign = Encoding.UTF8.GetBytes("Data to sign"); using (CngKey signingKey = CngKey.Import(pkcs8PrivateKey, CngKeyBlobFormat.Pkcs8PrivateBlob)) using (RSACng rsa = new RSACng(signingKey)) { rsa.SignatureHashAlgorithm = CngAlgorithm.MD5; return rsa.SignData(dataToSign); }
BouncyCastle
/// <summary> /// 获取数据签名 /// </summary> /// <param name="source">数据</param> /// <param name="keyPath">私钥文件路径</param> /// <returns>签名后的信息</returns> public static string GetSignString(string data, string keyPath) { if (string.IsNullOrEmpty(data)) { return string.Empty; } byte[] dataKey = File.ReadAllBytes(keyPath); var key = PrivateKeyFactory.CreateKey(dataKey); ISigner sig = SignerUtilities.GetSigner("MD5withRSA"); /* Populate key */ sig.Init(true, key); /* Get the bytes to be signed from the string */ var bytes = Encoding.UTF8.GetBytes(data); /* Calc the signature */ sig.BlockUpdate(bytes, 0, bytes.Length); byte[] signature = sig.GenerateSignature(); /* Base 64 encode the sig so its 8-bit clean */ //var signedstring = Convert.ToBase64String(signature); return signature.ToBase64(); }
OpenSSL
byte[] msg = System.Text.Encoding.ASCII.GetBytes("text to encrypt"); OpenSSL.Crypto.RSA rsa = new OpenSSL.Crypto.RSA(); byte[]result = rsa.PrivateEncrypt(msg, OpenSSL.Crypto.RSA.Padding.None); Console.WriteLine(Convert.ToBase64String(result));
NET采用的加密填充标准是PKCS1Padding,由于java的rsa默认的加密没有使用填充算法,导致采用同样的秘钥加密的结果都不一样,其实java同样支持这一填充标准
//进行加密 参数“RSA/ECB/PKCS1Padding”,代表和.NET用相同的填充算法
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] enBytes = cipher.doFinal(str_m.getBytes());
String s = (new BASE64Encoder()).encodeBuffer(enBytes);
System.out.println("加密结果为:" + s);