RSA加密算法java编程实现
RSA算法 JS加密 JAVA解密

RSA算法JS加密JA V A解密有这样一个需求,前端登录的用户名密码,密码必需加密,但不可使用MD5,因为后台要检测密码的复杂度,那么在保证安全的前提下将密码传到后台呢,答案就是使用RSA非对称加密算法解决。
java代码需要依赖commons-codec 包RSACoder.Javaimport mons.codec.binary.Base64;import javax.crypto.Cipher;import java.security.*;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;/*** Created by lake on 17-4-12.*/public class RSACoder {public static final String KEY_ALGORITHM = "RSA";public static final String SIGNA TURE_ALGORITHM = "MD5withRSA";private static final String PUBLIC_KEY = "RSAPublicKey";private static final String PRIV ATE_KEY = "RSAPrivateKey";public static byte[] decryptBASE64(String key) {return Base64.decodeBase64(key);}public static String encryptBASE64(byte[] bytes) {return Base64.encodeBase64String(bytes);}/*** 用私钥对信息生成数字签名** @param data 加密数据* @param privateKey 私钥* @return* @throws Exception*/public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64编码的私钥byte[] keyBytes = decryptBASE64(privateKey);// 构造PKCS8EncodedKeySpec对象PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取私钥匙对象PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);// 用私钥对信息生成数字签名Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(priKey);signature.update(data);return encryptBASE64(signature.sign());}/*** 校验数字签名** @param data 加密数据* @param publicKey 公钥* @param sign 数字签名* @return 校验成功返回true 失败返回false* @throws Exception*/public static boolean verify(byte[] data, String publicKey, String sign)throws Exception {// 解密由base64编码的公钥byte[] keyBytes = decryptBASE64(publicKey);// 构造X509EncodedKeySpec对象X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取公钥匙对象PublicKey pubKey = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(pubKey);signature.update(data);// 验证签名是否正常return signature.verify(decryptBASE64(sign));}public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{ // 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 解密<br>* 用私钥解密** @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPrivateKey(String data, String key)throws tion {return decryptByPrivateKey(decryptBASE64(data),key);}/*** 解密<br>* 用公钥解密** @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPublicKey(byte[] data, String key)throws Exception {// 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 加密<br>* 用公钥加密** @param data* @param key* @return* @throws Exception*/public static byte[] encryptByPublicKey(String data, String key)throws Exception {// 对公钥解密byte[] keyBytes = decryptBASE64(key);// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data.getBytes());}/*** 加密<br>* 用私钥加密** @param data* @param key* @return* @throws Exception*/public static byte[] encryptByPrivateKey(byte[] data, String key)throws Exception {// 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 取得私钥** @param keyMap* @return* @throws Exception*/public static String getPrivateKey(Map<String, Key> keyMap)throws Exception {Key key = (Key) keyMap.get(PRIV ATE_KEY);return encryptBASE64(key.getEncoded());}/*** 取得公钥** @param keyMap* @return* @throws Exception*/public static String getPublicKey(Map<String, Key> keyMap)throws ption {Key key = keyMap.get(PUBLIC_KEY);return encryptBASE64(key.getEncoded());}/*** 初始化密钥** @return* @throws Exception*/public static Map<String, Key> initKey() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();Map<String, Key> keyMap = new HashMap(2);keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥keyMap.put(PRIV ATE_KEY, keyPair.getPrivate());// 私钥return keyMap;}}测试类RSACoderTest.javaimport org.junit.Before;import org.junit.Test;import java.security.Key;import java.util.Map;import static org.junit.Assert.assertEquals;import static org.junit.Assert.assertTrue;/*** Created by lake on 17-4-12.*/public class RSACoderTest {private String publicKey;private String privateKey;@Beforepublic void setUp() throws Exception {Map<String, Key> keyMap = RSACoder.initKey();publicKey = RSACoder.getPublicKey(keyMap);privateKey = RSACoder.getPrivateKey(keyMap);System.err.println("公钥: \n\r" + publicKey);System.err.println("私钥:\n\r" + privateKey);}@Testpublic void test() throws Exception {System.err.println("公钥加密——私钥解密");String inputStr = "abc";byte[] encodedData = RSACoder.encryptByPublicKey(inputStr, publicKey);byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,teKey);String outputStr = new String(decodedData);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);assertEquals(inputStr, outputStr);}@Testpublic void testSign() throws Exception {System.err.println("私钥加密——公钥解密");String inputStr = "sign";byte[] data = inputStr.getBytes();byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);String outputStr = new String(decodedData);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);assertEquals(inputStr, outputStr);System.err.println("私钥签名——公钥验证签名");// 产生签名String sign = RSACoder.sign(encodedData, privateKey);System.err.println("签名:" + sign);// 验证签名boolean status = RSACoder.verify(encodedData, publicKey, sign);System.err.println("状态:" + status);assertTrue(status);}}前端代码依赖jsencrypt 项目<script src="bin/jsencrypt.min.js"></script><script type="xt/javascript">var encrypt = new JSEncrypt();encrypt.setPublicKey('java生成的公钥');var encrypted = encrypt.encrypt('加密的字符串');</script>说明前端生成加密的字符串encrypted,传到后台,java使用私钥进行解密即可。
C#与JavaRsa加密与解密互通

C#与JavaRsa加密与解密互通Rsa 加密标准的制定已经过去了⼗多年了. 这两天在看rsa 加密的⽂章,基本上都是在说 .net 与 java 之间的 rsa加密是不能互通的.因为项⽬有⽤到,所以花了点时间对rsa加密做了⼀点点了解,发现,不管是java 还是 C# 都对 rsa 的标准加密进⾏了实现, 是对于标准是实现,不能互通就讲不过去了. 今天特意写了⼀段java 代码试了⼀下,发现是完全可以的.密钥的描述: C#(.net) 中有三种⽅式导出密钥,⼀种是blob,⼀种是 xml 另⼀种是参数,其中xml 的⽅式是把参数进⾏了 xml序列化.blob 的形式我没看懂是什么意思,只知道⽂档上说是给微软的什么api⽤的,下⾯给出其参数的形式.RSAParameters 字段Contains对应的 PKCS #1 字段d,私钥指数privateExponentd mod (p - 1) exponent1d mod (q - 1) exponent2e,公钥指数publicExponent(InverseQ)(q) = 1 mod p coefficientn modulusp prime1q prime2RSA 算法若要⽣成密钥对,可以从创建名为 p 和 q 的两个⼤的质数开始; 这两个数相乘,结果称为 n; 因为 p 和 q 都是质数,所以 n 的全部因数为 1、p、q 和 n;如果仅考虑⼩于 n 的数,则与 n 为互质数(即与 n 没有公因数)的数的个数等于 (p - 1)(q - 1);现在,选择⼀个数 e,它与计算的值为互质数; 则公钥表⽰为 {e, n};若要创建私钥,则必须计算 d,它是满⾜ (d)(e) mod n = 1 的⼀个数; 根据 Euclidean 算法,私钥为 {d, n};纯⽂本 m 到密码⽂本 c 的加密定义为 c = (m ^ e) mod n; 解密则定义为 m = (c ^ d) mod n;总之,我们可以从 .net 的rsa 中拿到合适的密钥描述就是了,⾄于 java的,我想也是可以做到的,⽽且通常密钥是应该放在密钥容器的.接下来我们⽤.net ⽣成⼀个 rsa 的密钥,以⼗六进制的⽅式输出的(new ⼀个RSACryptoServiceProvider,把密钥导出就可以了)D: 2FE7479CF4CFEE63218C44D763C3E552DC5FBC94A31F944B88AE8E58F0ED16874B8BED35307B143F413761B2ECFFC95F48DF0D0A29FC155C0B968EFE9FFF36E7DP: 6777B761BC29637622FC63682243BB2E05CCFC6FF710ADE1DCE6B0C843B17C4FDQ: 68771CCDA40F0DA0B504C438BB03F7DF30F77364094D475E70270D148260D247Exponent: 010001InverseQ: 5665AB47697008CC2CECB544B582B9C50628281C400846C1E736629B03FE5C85Modulus: B3F276C8EDF515FD3248CCF4163480B9F77443A666522D66B89411EC6DFE11DEA917A97C977750EE777DACBD4D2C11BC363FDC110E5CCA0A1361D51AFA4A7ADDP: ECC60A01B1BDCBA1C5422D8A0A34FC0E46727DB4ED5089E54C356F052E0AB573Q: C28F233948483D0CD0E3FA7B5D2955F2B15E831B38876FB0E7180D873EDF7A6F为了⽅便写.net 代码,这⾥贴⼀下blob的密钥0702000000A40000525341320002000001000100DD7A4AFA1AD561130ACA5C0E11DC3F36BC112C4DBDAC7D77EE5077977CA917A9DE11FE6DEC1194B8662D5266A64374F7B9803416F4CC4832FD15F5EDC876F2B373B50A2E056F354CE58因为是私钥,所以同时可以加密和解密.下⾯上 C# 代码,⽐较简单using System;using System.Security.Cryptography;class Program{public static void Main(string[] args){byte[] plainText = new byte[]{0,1,2,3,4,5};byte[] cipherText;byte[] key = String2Bytes("0702000000A40000525341328001000001000100D3D10816051881319774576B67B1D24F3AA303471A4402AB625208EC1CB04D508AF2098227C5EE185890ECB83E6971C12BDCF4F8AB0FD729167C815D34 using(var rsa = new RSACryptoServiceProvider()){rsa.ImportCspBlob(key);Console.WriteLine("OAEP:");Console.WriteLine(Bytes2String(rsa.Encrypt(plainText, true)));Console.WriteLine("PCSK1-v1_5:");Console.WriteLine(Bytes2String(rsa.Encrypt(plainText, false)));}Console.Write("Press any key to continue . . . ");Console.ReadKey(true);}const string pattern = @"[^0-9a-fA-F]+";static byte[] String2Bytes(string str){str = System.Text.RegularExpressions.Regex.Replace(str, pattern, "");if (str == string.Empty)return null;byte[] data = new byte[str.Length / 2];for (int i = 0; i < data.Length; ++i)data[i] = byte.Parse(str.Substring(2 * i, 2), System.Globalization.NumberStyles.HexNumber);return data;}static string Bytes2String(byte[] data){System.Text.StringBuilder builder = new System.Text.StringBuilder();foreach (var element in data) {builder.AppendFormat("{0:X2}",element);}return builder.ToString();}}运⾏后输出(rsa加密,密⽂每次都不⼀定⼀样):OAEP:87F04B0F28B81D23E63DA71C8278E0B7E357F40583BDDCAB493D44A58080EB178EC8E0DB0DCD4BE5427FDB8190229B8DF2511BDA1082607C92BD03B0615D5AD3 PCSK1-v1_5:358AB4D336D0C35DAE3895E8A125F4F5AD0FB58117A4100FAF15DE95FF8615F01FFB1A59C9B579792B7C14E93E54A3E7E236D464DDB93D8DF9D96F63F46BACD7现在我们有密⽂了,⾄于.net 的解密 .net 加密后的密⽂,我没兴趣去看,反正铁定可以的就是了.下⾯我们写java 的解密部分package rsatest;import java.math.BigInteger;import java.security.KeyFactory;import java.security.PrivateKey;import java.security.PublicKey;import java.security.spec.RSAPrivateKeySpec;import java.security.spec.RSAPublicKeySpec;import javax.crypto.Cipher;public class RsaTest {public static void main(String[] args) throws Exception {//前⾯补了个0,符号位为0,表⽰⾮负BigInteger n = new BigInteger("B3F276C8EDF515FD3248CCF4163480B9F77443A666522D66B89411EC6DFE11DEA917A97C977750EE777DACBD4D2C11BC363FDC110E5CCA0A1361D51AFA4A7ADD", 16); BigInteger e = new BigInteger("010001", 16);BigInteger d = new BigInteger("2FE7479CF4CFEE63218C44D763C3E552DC5FBC94A31F944B88AE8E58F0ED16874B8BED35307B143F413761B2ECFFC95F48DF0D0A29FC155C0B968EFE9FFF36E7", 16);RSAPublicKeySpec keySpec = new RSAPublicKeySpec(n, e);PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);RSAPrivateKeySpec prvKeySpec = new RSAPrivateKeySpec(n, d);PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(prvKeySpec);//现在key 准备好了,把前⾯的密⽂放这⾥解密byte[] oaepCiphertext = Hex2Bytes("87F04B0F28B81D23E63DA71C8278E0B7E357F40583BDDCAB493D44A58080EB178EC8E0DB0DCD4BE5427FDB8190229B8DF2511BDA1082607C92BD03B0615D5AD3");//解密OAEP 加密的数据Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] plaintext = cipher.doFinal(oaepCiphertext);System.out.println(Bytes2Hex(plaintext));//解密PKCS1-v1_5 加密的数据byte[] ciphertext = Hex2Bytes("358AB4D336D0C35DAE3895E8A125F4F5AD0FB58117A4100FAF15DE95FF8615F01FFB1A59C9B579792B7C14E93E54A3E7E236D464DDB93D8DF9D96F63F46BACD7");cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);plaintext = cipher.doFinal(ciphertext);System.out.println(Bytes2Hex(plaintext));}public static byte[] Hex2Bytes(String hexStr) {if (hexStr.length() % 2 != 0) {hexStr = "0" + hexStr;}byte[] bytes = new byte[hexStr.length() / 2];for (int i = 0; i < bytes.length; ++i) {bytes[i] = (byte) Integer.parseUnsignedInt(hexStr.substring(i * 2, i * 2 + 2), 16);}return bytes;}public static String Bytes2Hex(byte[] bytes) {StringBuilder builder = new StringBuilder();for (byte b : bytes) {builder.append(String.format("%02X", b));}return builder.toString();}}程序运⾏后输出:000102030405000102030405跟我们预期的是⼀样的.我们再⽤java 对明⽂加密,代码⽚段// plaintext {0,1,2,3,4,5}cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");cipher.init(Cipher.ENCRYPT_MODE, publicKey);oaepCiphertext = cipher.doFinal(plaintext);System.out.println("OAEP:");System.out.println(Bytes2Hex(oaepCiphertext));cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);ciphertext = cipher.doFinal(plaintext);System.out.println("PCSK1-v1_5:");System.out.println(Bytes2Hex(ciphertext));对应输出(rsa加密,密⽂每次都不⼀定⼀样):OAEP:3144C4CB06C7F49D31E65D09C840069F7CCF602487908CCEAB33D473B949199E1795530B69E1FA20EB59E392B2B934024D46E979DEA1682BDFA61D6FDD980F9C PCSK1-v1_5:699A694BEB75616879C6B8D311CC10D987EA109D494EE6C9380CD2C02A124613F130C440CB1CA6D3405E50B62CF96A79EB43C3370253E5D8C1A9132CFE01D686接下来⽤C# 对数据解密,代码⽚段//还是⽤之前那个rsa对象//OAEPcipherText = String2Bytes("3144C4CB06C7F49D31E65D09C840069F7CCF602487908CCEAB33D473B949199E1795530B69E1FA20EB59E392B2B934024D46E979DEA1682BDFA61D6FDD980F9C"); Console.WriteLine(Bytes2String(rsa.Decrypt(cipherText, true)));//PCSK1-v1_5cipherText = String2Bytes("699A694BEB75616879C6B8D311CC10D987EA109D494EE6C9380CD2C02A124613F130C440CB1CA6D3405E50B62CF96A79EB43C3370253E5D8C1A9132CFE01D686"); Console.WriteLine(Bytes2String(rsa.Decrypt(cipherText, false)));对应的输出:000102030405000102030405解密也成功了.或许该头疼的问题是,已知 {e,n} 或者 {d,n} 怎么⽣成.net 使⽤的密钥.。
使用Java实现安全性加密与解密

使用Java实现安全性加密与解密在当今信息时代,数据的安全性越来越受到重视。
无论是个人的隐私信息还是企业的商业机密,都需要得到有效的保护。
而加密与解密技术就是一种常用的保护数据安全的手段。
本文将介绍如何使用Java语言实现安全性加密与解密。
1. 加密与解密的基本概念加密是将明文转换为密文的过程,而解密则是将密文转换回明文的过程。
加密算法通常使用一个密钥,密钥用于控制加密过程的转换规则,只有拥有正确的密钥才能进行解密。
常见的加密算法有对称加密算法和非对称加密算法。
对称加密算法使用相同的密钥进行加密和解密,速度较快,但密钥的传输和管理相对困难。
非对称加密算法使用一对密钥,公钥用于加密,私钥用于解密,安全性较高,但速度较慢。
2. 使用Java实现对称加密Java提供了多种对称加密算法的实现,如DES、AES等。
下面以AES算法为例,介绍如何使用Java实现对称加密。
首先,需要导入Java加密扩展(JCE)的包。
在Java 8及以上版本中,JCE已经被默认包含在JDK中,无需额外导入。
接下来,可以使用以下代码进行AES加密:```javaimport javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;public class AESUtil {private static final String ALGORITHM = "AES";public static String encrypt(String plainText, String key) throws Exception {KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);keyGenerator.init(128);SecretKey secretKey = keyGenerator.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, ALGORITHM);Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());return Base64.getEncoder().encodeToString(encryptedBytes);}public static String decrypt(String encryptedText, String key) throws Exception {KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);keyGenerator.init(128);SecretKey secretKey = keyGenerator.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, ALGORITHM);Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);byte[] decryptedBytes = cipher.doFinal(encryptedBytes);return new String(decryptedBytes);}}```以上代码中,`encrypt`方法用于对明文进行加密,`decrypt`方法用于对密文进行解密。
RSA算法签名技术Java与C++统一(加密解密结果一样)

RSA算法签名技术Java与C++统一(加密解密结果一样)源代码下载地址:/product_down/rsa_c++_java.rar一、介绍:RSA 算法的介绍:公钥加密、私钥解密或私钥加密、公钥解密,这样们可以在终端软件公开我们的公钥而不会影响安全性。
RSA这种特点常用在电信、等行业数字签名中。
SHA-1 算法的介绍:从一段字符串中计算出唯一标识这段字符串的信息摘要(160bit位=20位字符)和md5算法类似。
RSA、SHA-1算法在网上都有很详细的介绍不是本文介绍重点,本文重点介绍RSA算法在完成加密解密及数字签名过程中用不同开发语言对接的问题(java与c++)对于其它开发语言例如vb、delphi、pb等可以调用c++的lib、dll库文件来完成。
二、数字签名流程1、A构建密钥对,将公钥公布给B1...B2,将私钥保留。
2、A使用私钥加密数据,然后对加密后的数据签名(签名算法:密文=rsa(明文,privatekey),Sgn=sha-1(密文) ,发送给B1..B2;B1..B2使用Sign来验证待解密数据是否有效,如果有效使用公钥对数据解密rsa(密文,publickey)、。
3、B1..B2使用公钥加密数据rsa(明文,publickey),向A发送经过加密后的数据;A 获得加密数据,通过私钥解密rsa密文,privatekey)。
4、数字只起到数据在网络传送中验证否被篡改过并保证加密数据的完整性。
而RSA数据的安全是由RSA算法来完成的。
(工作流程图如下:)三、Java与C++等开发语言RSA算法统一性分析要完成上面的数字签名技术关键是对RSA算法在不同开发语言中标准一致,从而达到RSA能正确加密、解密。
1.JA V A是开源可破解的并且RSA算法封装的很好所以在网站找到用java实现RSA数字例子很容易。
这里们提供你个很典型的JA V A实现RSA加密及数字签名例子。
2.下载地址:/product_down/rsa_c++_java.rar3.JA V A生产密钥对(伪代码):private String publicKey;private String privateKey;Map<String, Object> keyMap = RSACoder.initKey();publicKey = RSACoder.getPublicKey(keyMap);privateKey = RSACoder.getPrivateKey(keyMap);System.err.println("公钥: \n\r" + publicKey);System.err.println("私钥:\n\r" + privateKey);那么我们发现JA V A采用的公钥、私钥与标准的算法说的公钥=E+M、私钥=D+M 不同那么我们如何通过JA V A的publickey、privatekey获得E、D、M呢?4.分解java公钥、私钥:BigInteger e = publicKey.getPublicExponent();BigInteger n =publicKey.getModulus();BigInteger d = privateKey.getPrivateExponent();BigInteger m = privateKey.getModulus();System.out.println("==============C++程序密钥==================");System.out.println("因子E:"+e.toString()+"\r\n");System.out.println("因子D:"+d.toString()+"\r\n");System.out.println("因子N:"+n.toString()+"\r\n");System.out.println("因子M:"+m.toString()+"\r\n");这样我们就获得啦E、D、M 从而达到啦JA V A密钥与C++等开发语言密钥的一致性。
Java使用Cipher类实现加密,包括DES,DES3,AES和RSA加密

Java使⽤Cipher类实现加密,包括DES,DES3,AES和RSA加密⼀、先看⼀个简单加密,解密实现1.1 加密/*** content: 加密内容* slatKey: 加密的盐,16位字符串* vectorKey: 加密的向量,16位字符串*/public String encrypt(String content, String slatKey, String vectorKey) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");IvParameterSpec iv = new IvParameterSpec(vectorKey.getBytes());cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);byte[] encrypted = cipher.doFinal(content.getBytes());return Base64.encodeBase64String(encrypted);}1.2 解密/*** content: 解密内容(base64编码格式)* slatKey: 加密时使⽤的盐,16位字符串* vectorKey: 加密时使⽤的向量,16位字符串*/public String decrypt(String base64Content, String slatKey, String vectorKey) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");IvParameterSpec iv = new IvParameterSpec(vectorKey.getBytes());cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);byte[] content = Base64.decodeBase64(base64Content);byte[] encrypted = cipher.doFinal(content);return new String(encrypted);}1.3 代码解释上⾯简单实现了AES("AES/CBC/PKCS5Padding")的加密和解密。
如何利用java程序实现加密所需的公钥、密钥、数字证书

如何利⽤java程序实现加密所需的公钥、密钥、数字证书本篇的主要⽬的在于实现pdf的数字签名问题,只是作为我学习知识的总结。
1、数字签名算法的概述数字签名:私钥⽤于签名,公钥⽤于验证。
数字签名的作⽤:验证数据的完整性,认证数据来源,抗否认。
数字签名实现的具体原理:1、将报⽂按双⽅约定的HASH算法计算得到⼀个固定位数的报⽂摘要。
在数学上保证,只要改动报⽂中任何⼀位,重新计算出的报⽂摘要值就会与原先的值不相符。
这样就保证了报⽂的不可更改性。
(详见参考资料的"公钥密码技术原理"章节)2、将该报⽂摘要值⽤发送者的私⼈密钥加密,然后连同原报⽂和数字证书(包含公钥)⼀起发送给接收者⽽产⽣的报⽂即称数字签名。
3、接收⽅收到数字签名后,⽤同样的HASH算法对报⽂计算摘要值,然后与⽤发送者的公开密钥进⾏解密解开的报⽂摘要值相⽐较,如相等则说明报⽂确实来⾃所称的发送者。
4、同时通过证书颁发机构CA确认证书的有效性即可确认发送的真实⾝份。
常⽤的数字签名有:RSA、DSA、ECDSA2、RSA算法概述RSA是⽬前为⽌应⽤最为⼴泛的⾮对称加密算法。
⾮对称加密算法简单的说就是分成公钥和私钥。
加密和解密采⽤不同的算法实现,这样的好处是不需要像传统对称加密算法⼀样将相同算法的密钥分发给对⽅,从⽽减少密钥被获取所带来的严重危害,⽬前基本上都是采⽤⾮对称算法,⽽RSA是最为⼴泛的。
理论上1024位以上的RSA是⽆法破解的(或者未公开)。
基本原理:⾮对称算法将密码将密码分为公钥和私钥,公钥发送给⽤户(可以是多个),⽤户⽤公钥加密想要发送的数据,然后发送给服务器,服务器通过私钥解密加密后的数据。
基本步骤:⽣成公钥和私钥步骤:1. 随机选择两个不相等的质数p和q2. 计算p和q的乘积n (n的长度就是密钥长度。
3233写成⼆进制是110010100001,⼀共有12位,所以这个密钥就是12位。
实际应⽤中,RSA密钥⼀般是1024位,重要场合则为2048位。
JAVARSA私钥加密(签名)对应C#RSA私钥加密(签名)

JAVARSA私钥加密(签名)对应C#RSA私钥加密(签名)⾮对称密钥RSA算法加解密在C#和Java之间交互的问题,这两天看了很多其他⼈写的⽂章,碰到了⼏个问题,最终解决问题。
需求⽬的:完成c#请求端RSA加密(签名)问题,客户端采⽤C#开发,服务器端采⽤Java开发。
服务器端给客户端提供私钥,进⾏数据加密(签名),客户端加密(签名)后提数据提交给服务器,服务器⽤公钥对数据解密,进⾏验证。
解决过程碰到的问题:1.JAVA 需要的 RSA私钥格式和 C# 需要的 RSA私钥不⼀致。
JAVA 需要是 PKCS8格式私钥:-----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOwuOHH/OIRE+0ifmEPYGuhYRTyKdd6VLFIsNqy/SO5xZitHfA7xEymJKnpEUGgDJKr5zbFbytnWs5Jjgen6TXkUh9LG/fhPGGHdUVB42pAHv5yzoyEaOnJxBAxd6UstoWTaEgbT6GUbzMr/Az25zuxw7c+skAlnUETVE5GL3tD7AgMBAAECgYEAxdNZODMctb3J9OSo93rV3vPA2prna87rVtDt4vg+MGsPtwSjZyiKcmoQCGWcK+MmHYgrwHkwihKKSv3KXZ9or3xQ2wNZGuTHLymWEzqfEfVb0igvxbe85EGwsaN3qSK62CK8vok/Bi+fZVa3UNCn0WFslUS0qn+K3SECM9I1iwECQQD+2Pl2AJGQs2bRXSsnJk0FIwjpqdpGZFPlAUYaXkuTMqpwefP/bwwiuWqq9QIt2vAAKgy5T16tpPBcGpT6cvxBAkEA7T+i1gVwrXcozTuT9oCwkF2MGBaXkv3mN9H/Pfy/oIhTsgiDxX8t+0KapAEQogvCuAOq19JvGw5e91H2g0suOwJAJOMnCIuAhl9RTJCdxGbo0wuFKL0rGPFAq28JxJtNeRrmTK16QcjDCuunouMf059TCdMMUG5Kl/u9xrcaRT4LgQJAZPiUYOnnzqvMHayhiGO0wXxOx2G2GMUeWdtx+fu7wqLCnB6rlj5OX4U1M1+QqKbAtHg7Gadhye4P1Mp5U9+HSQJBANLVzcCXyAX2D12UPTPkhcNRaCRXFp3aJGMxI4iluUC+ukAdiapohqZ7vMQyWRq/tDyiwjirqMcg/AJIuQWmPyc=-----END PRIVATE KEY-----C# 需要的是 PKCS1 格式私钥:-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQDsLjhx/ziERPtIn5hD2BroWEU8inXelSxSLDasv0jucWYrR3wO8RMpiSp6RFBoAySq+c2xW8rZ1rOSY4Hp+k15FIfSxv34Txhh3VFQeNqQB7+cs6MhGjpycQQMXelLLaFk2hIG0+hlG8zK/wM9uc7scO3PrJAJZ1BE1RORi97Q+wIDAQABAoGBAMXTWTgzHLW9yfTkqPd61d7zwNqa52vO61bQ7eL4PjBrD7cEo2coinJqEAhlnCvjJh2IK8B5MIoSikr9yl2faK98UNsDWRrkxy8plhM6nxH1W9IoL8W3vORBsLGjd6kiutgivL6JPwYvn2VWt1DQp9FhbJVEtKp/it0hAjPSNYsBAkEA/tj5dgCRkLNm0V0rJyZNBSMI6anaRmRT5QFGGl5LkzKqcHnz/28MIrlqqvUCLdrwACoMuU9eraTwXBqU+nL8QQJBAO0/otYFcK13KM07k/aAsJBdjBgWl5L95jfR/z38v6CIU7IIg8V/LftCmqQBEKILwrgDqtfSbxsOXvdR9oNLLjsCQCTjJwiLgIZfUUyQncRm6NMLhSi9KxjxQKtvCcSbTXka5kytekHIwwrrp6LjH9OfUwnTDFBuSpf7vca3GkU+C4ECQGT4lGDp586rzB2soYhjtMF8TsdhthjFHlnbcfn7u8Kiwpweq5Y+Tl+FNTNfkKimwLR4OxmnYcnuD9TKeVPfh0kCQQDS1c3Al8gF9g9dlD0z5IXDUWgkVxad2iRjMSOIpblAvrpAHYmqaIame7zEMlkav7Q8osI4q6jHIPwCSLkFpj8n-----END RSA PRIVATE KEY-----2.私钥格式之间的转换问题java 代码,注意这⾥的私钥:是Pem私钥⽂件中去除头(-----BEGIN PRIVATE KEY-----)和尾(-----END PRIVATE KEY-----)以及换⾏符后的字符串1 /**2 * @data: 待加密的字符串3 * @privateKey: 私钥4 */5 public static String sign(byte[] data, String privateKey) throws Exception {67 byte[] keyBytes = new BASE64Decoder().decodeBuffer(privateKey);8 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);910 KeyFactory keyFactory = KeyFactory.getInstance("RSA");1112 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);1314 Signature signature = Signature.getInstance("SHA1withRSA");15 signature.initSign(priKey);16 signature.update(data);1718 return byte2hex(signature.sign());19 }c# 代码,注意这⾥的私钥:是Pem私钥⽂件中去除头(-----BEGIN RSA PRIVATE KEY-----)和尾(-----END RSA PRIVATE KEY-----)以及换⾏符后的字符串1 /// <summary>2 /// 签名3 /// </summary>4 /// <param name="data">待加密的字符串</param>5 /// <param name="privateKey">私钥</param>6 /// <returns></returns>7 public static string Sign(string data, string privateKey)8 {9 RSACryptoServiceProvider rsaCsp = LoadCertificate(privateKey);10 byte[] dataBytes = Encoding.UTF8.GetBytes(data);11 byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");12 return Hex_2To16(signatureBytes);13 }1415 private static RSACryptoServiceProvider LoadCertificate(string privateKey)16 {17 byte[] res = res = Convert.FromBase64String(privateKey);18 try19 {20 RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res);21 return rsa;22 }23 catch (Exception ex)24 {25 }26 return null;27 }2829 private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)30 {31 byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;3233 // --------- Set up stream to decode the asn.1 encoded RSA private key ------34 MemoryStream mem = new MemoryStream(privkey);35 BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading36 byte bt = 0;37 ushort twobytes = 0;38 int elems = 0;39 try40 {41 twobytes = binr.ReadUInt16();42 if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)43 binr.ReadByte(); //advance 1 byte44 else if (twobytes == 0x8230)45 binr.ReadInt16(); //advance 2 bytes46 else47 return null;4849 twobytes = binr.ReadUInt16();50 if (twobytes != 0x0102) //version number51 return null;52 bt = binr.ReadByte();53 if (bt != 0x00)54 return null;555657 //------ all private key components are Integer sequences ----58 elems = GetIntegerSize(binr);59 MODULUS = binr.ReadBytes(elems);6061 elems = GetIntegerSize(binr);62 E = binr.ReadBytes(elems);6364 elems = GetIntegerSize(binr);65 D = binr.ReadBytes(elems);6667 elems = GetIntegerSize(binr);68 P = binr.ReadBytes(elems);6970 elems = GetIntegerSize(binr);71 Q = binr.ReadBytes(elems);7273 elems = GetIntegerSize(binr);74 DP = binr.ReadBytes(elems);7576 elems = GetIntegerSize(binr);77 DQ = binr.ReadBytes(elems);7879 elems = GetIntegerSize(binr);80 IQ = binr.ReadBytes(elems);818283 // ------- create RSACryptoServiceProvider instance and initialize with public key -----84 CspParameters CspParameters = new CspParameters();85 CspParameters.Flags = eMachineKeyStore;86 RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);87 RSAParameters RSAparams = new RSAParameters();88 RSAparams.Modulus = MODULUS;89 RSAparams.Exponent = E;90 RSAparams.D = D;91 RSAparams.P = P;92 RSAparams.Q = Q;93 RSAparams.DP = DP;94 RSAparams.DQ = DQ;95 RSAparams.InverseQ = IQ;96 RSA.ImportParameters(RSAparams);97 return RSA;98 }99 catch (Exception ex)100 {101 return null;102 }103 finally104 {105 binr.Close();106 }107 }108109 private static int GetIntegerSize(BinaryReader binr)110 {111 byte bt = 0;112 byte lowbyte = 0x00;113 byte highbyte = 0x00;114 int count = 0;115 bt = binr.ReadByte();116 if (bt != 0x02) //expect integer117 return 0;118 bt = binr.ReadByte();119120 if (bt == 0x81)121 count = binr.ReadByte(); // data size in next byte122 else123 if (bt == 0x82)124 {125 highbyte = binr.ReadByte(); // data size in next 2 bytes126 lowbyte = binr.ReadByte();127 byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };128 count = BitConverter.ToInt32(modint, 0);129 }130 else131 {132 count = bt; // we already have the data size133 }134135 while (binr.ReadByte() == 0x00)136 { //remove high order zeros in data137 count -= 1;138 }139 binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte 140 return count;141 }142143144 /// <summary>145 /// 2进制转16进制146 /// </summary>147 public static String Hex_2To16(Byte[] bytes)148 {149 String hexString = String.Empty;150 Int32 iLength = 65535;151 if (bytes != null)152 {153 StringBuilder strB = new StringBuilder();154155 if (bytes.Length < iLength)156 {157 iLength = bytes.Length;158 }159160 for (int i = 0; i < iLength; i++)161 {162 strB.Append(bytes[i].ToString("X2"));163 }164 hexString = strB.ToString(); 165 }166 return hexString;167 }。
利用DES和RSA加密算法实现JAVA软件的注册授权策略

利用这个原理 , 我们 可以将类文件进行 加密 保存 , J M装 人 的 时候 对 Casodr 在 V l Lae 进行 定 s 制, 使之能找到经过加密后 的类代码 , 并对这些代 码进行解密后装载到 JM。由于解密后的字节码 V 文件保存在 内存 中, 以窃密者很难 得到解密后 所 的代码 。于是源代码加密的重点就转移到了对编
制 J M 把 该类 以及 所 有它 所需 要 的类关 联 到定 制 V
在 这里 , 们采 用 D S D t E cytnSad 我 E ( aa nrpi t o n
a) r 算法对类文件 的字节码进 行加密 和解 密, d 它
包 含在 J E软件 包 中 的 SnC rv e 中 。D S C uJ EPoi r d E
张 俊
( 青岛市住房保障中心 , 山东 青 岛 267 ) 60 1
提 要: 通过 J I 口调 用本 地 应 用程 序 读 取 用 户 主 机 的 硬 盘序 列 号作 为 用 户唯 一性 依 N接
据, 利用 R A加密算法实现用户信息和注册信息的加密保护和验证。本文介绍 了在 商用 J V S AA 软件开发过程中可以使用的一种注册验证策略的实现方法。 关 键词 : J VM 反 编译 加 密算 法 D S R A MD J I 硬盘 序 列号 E S 5 N
1 源 代码 加密
后 的类文件进行解密 。但解 密之 后 , 最终用户就 有 了一份不 加密的类文件 , 这和事先不进行加 密 没有 什么 差别 。 为了找到合适 的加密方法 , 我们需要从 Jv aa 程序在 J M上的执行过程人手。J M每次装人类 V V 文件时都需要一个称 为 Ca Lae 的对象 , l sodr s 这个 对象负责把新的类装人正在运行 的 J M。J M给 V V Ca Lae 一个包含 了待装人类 ( l sodr s 比如 j a 1 g a .a . v n O j t名字的字符 串, b c) e 然后 由 Casodr l L ae 负责找 s 到类文件 , 装人原始数据 , 并把它转换成一个 Ca ls s
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、RSA加密算法的原理
(1)、RSA算法描述
RSA公钥密码体制的基本原理:根据数论,寻求两个大素数比较简单,而将他们的乘积分解开则极为困难。
(2)、RSA算法密钥计算过程:
1.用户秘密选取两个大素数p 和q,计算n=pq,n称为
RSA算法的模数,公开。
2.计算出n的欧拉函数Φ(n) = (p-1)×(q-1),保密。
3.从(1, Φ(n))中随机地选择一个与Φ(n)互素的数e作为加
密密钥,公开。
4.计算出满足下式的d 作为解密密钥,保密。
ed=1 mod Φ(n)
(3)、RSA算法密钥:
加密密钥PK = |e, n| 公开
解密密钥SK = |d, n| 保密
(4)、RSA算法加密解密过程:
RSA算法属于分组密码,明文在加密前要进行分组,分组
的值m 要满足:0 < m < n
加密算法:C = E(m) ≡me mod n
解密算法:m = D(c) ≡cd mod n
(5)、RSA算法的几点说明:
1.对于RSA算法,相同的明文映射出相同的密文。
2.RSA算法的密钥长度:是指模数n的长度,即n的二进
制位数,而不是e或d的长度。
3.RSA的保密性基于大数进行因式分解很花时间,因此,
进行RSA加密时,应选足够长的密钥。
512bit已被证明
不安全,1024bit也不保险。
4.RSA最快情况也比DES慢100倍,仅适合少量数据的加
密。
公钥e取较小值的方案不安全。
二.RSA公钥加密算法的编程实现
以下程序是java编写的实现RSA加密及解密的算法
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.Cipher;
//RSATest类即为测试类
public class RSATest {
//主函数
public static void main(String[] args) {
try {
RSATest encrypt = new RSATest();
String encryptText = "encryptText";//输入的明文
KeyPair keyPair = encrypt.generateKey();//调用函数生成密钥对,函数见下
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
byte[] e = encrypt.encrypt(publicKey, encryptText.getBytes());
//调用自己编写的encrypt函数实现加密,
byte[] de = encrypt.decrypt(privateKey, e);
//调用自己编写的decrypt函数实现解密,
System.out.println(toHexString(e)); //输出结果,采用ASSIC码形式
System.out.println(toHexString(de));
} catch (Exception e) {
e.printStackTrace();
}
}
// generateKey密钥对生成函数的实现
public KeyPair generateKey() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); //返回生成指定算法的public/private 密钥对的KeyPairGenerator 对象。
keyPairGen.initialize(1024, new SecureRandom());
//使用给定的随机源(和默认的参数集合)初始化确定密钥大小的密钥对生成器。
KeyPair keyPair = keyPairGen.generateKeyPair();//生成一个密钥对
return keyPair;
}
// encrypt加密函数
protected byte[] encrypt(RSAPublicKey publicKey, byte[] data) { if (publicKey != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
//返回实现指定转换的Cipher对象。
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//用密钥初始化此Cipher,第一个参数表示加密
return cipher.doFinal(data);
//按单部分操作加密或解密数据,或者结束一个多部分操作。
数据将被加密或解密(具体取决于此Cipher 的初始化方式)。
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
// decrypt解密函数
protected byte[] decrypt(RSAPrivateKey privateKey, byte[] raw) { if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey); //第一个参数表示解密
return cipher.doFinal(raw);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
// toHexString将字节数组变为ASSIC码表示的字符串
public static String toHexString(byte[] b) {
StringBuilder sb = new StringBuilder(b.length * 2);
//构造一个不带任何字符的字符串生成器,其初始容量由capacity参数指定。
for (int i = 0; i < b.length; i++) {
sb.append(HEXCHAR[(b[i] & 0xf0) >>> 4]);
// append方法始终将这些字符添加到生成器的末端;而insert方法则在指定的点添加字符。
//调用HEXCHAR方法
sb.append(HEXCHAR[b[i] & 0x0f]);
}
return sb.toString();
}
//构建一个HEXCHAR数组
private static char[] HEXCHAR = { '0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
}
小结:
RSA公开密钥的加密算法实现方法如上所述,我们先是调用API生成了RSA的密钥对,然后调用API实现了加密与解密,最终通过编译的函数实现了字符数组的字符串输出,且输出的是字符串的ASSIC.。