`
danwind
  • 浏览: 232820 次
  • 性别: Icon_minigender_1
  • 来自: 广东
社区版块
存档分类
最新评论

非对称加密之RSA,用javascript与java进行RSA加密与解密

    博客分类:
  • Java
阅读更多
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA的重大缺陷是无法从理论上把握它的保密性能如何,而且密码学界多数人士倾向于因子分解不是NPC问题。RSA的缺点主要有:A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。B)分组长度太大,为保证安全性,n 至少也要 600 bits以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。目前,SET(Secure Electronic Transaction)协议中要求CA采用2048比特长的密钥,其他实体使用1024比特的密钥。
  这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。
  RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数( 大于 100个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。

一.RSA用于安全登录:

具体实现思路如下:

1。服务端生成公钥与私钥,保存。

2。客户端在请求到登录页面后,随机生成一字符串。

3。后此随机字符串作为密钥加密密码,再用从服务端获取到的公钥加密生成的随机字符串。

4。将此两段密文传入服务端,服务端用私钥解出随机字符串,再用此私钥解出加密的密文。

这其中有一个关键是解决服务端的公钥,传入客户端,客户端用此公钥加密字符串后,后又能在服务端用私钥解出。

二.RSA主要类
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;

import com.elibrary.app.util.ConstrtsProperty;
import com.elibrary.core.ConfigurationManager;

/**
 * RSA 工具类。提供加密,解密,生成密钥对等方法。
 * 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。
 * 
 */
public class RSAUtil {
	/**
	 * * 生成密钥对 *
	 * 
	 * @return KeyPair *
	 * @throws EncryptException
	 */
	public static KeyPair generateKeyPair() throws Exception {
		try {
			KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			final int KEY_SIZE = 1024;// 没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
			keyPairGen.initialize(KEY_SIZE, new SecureRandom());
			KeyPair keyPair = keyPairGen.generateKeyPair();
			saveKeyPair(keyPair);
			return keyPair;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	public static KeyPair getKeyPair() throws Exception {
		String file = "D:/Java/eLibrary/config/RSAKey";//ConfigurationManager.getProperty(ConstrtsProperty.RSAFILE);
		FileInputStream fis = new FileInputStream(file);
		ObjectInputStream oos = new ObjectInputStream(fis);
		KeyPair kp = (KeyPair) oos.readObject();
		oos.close();
		fis.close();
		return kp;
	}

	public static void saveKeyPair(KeyPair kp) throws Exception {
		String file = "D:/Java/eLibrary/config/RSAKey";//ConfigurationManager.getProperty(ConstrtsProperty.DIR);
		FileOutputStream fos = new FileOutputStream(file);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		// 生成密钥
		oos.writeObject(kp);
		oos.close();
		fos.close();
	}

	/**
	 * * 生成公钥 *
	 * 
	 * @param modulus
	 *            *
	 * @param publicExponent
	 *            *
	 * @return RSAPublicKey *
	 * @throws Exception
	 */
	public static RSAPublicKey generateRSAPublicKey(byte[] modulus,
			byte[] publicExponent) throws Exception {
		KeyFactory keyFac = null;
		try {
			keyFac = KeyFactory.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
		} catch (NoSuchAlgorithmException ex) {
			throw new Exception(ex.getMessage());
		}

		RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(
				modulus), new BigInteger(publicExponent));
		try {
			return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
		} catch (InvalidKeySpecException ex) {
			throw new Exception(ex.getMessage());
		}
	}

	/**
	 * * 生成私钥 *
	 * 
	 * @param modulus
	 *            *
	 * @param privateExponent
	 *            *
	 * @return RSAPrivateKey *
	 * @throws Exception
	 */
	public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,
			byte[] privateExponent) throws Exception {
		KeyFactory keyFac = null;
		try {
			keyFac = KeyFactory.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
		} catch (NoSuchAlgorithmException ex) {
			throw new Exception(ex.getMessage());
		}

		RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(
				modulus), new BigInteger(privateExponent));
		try {
			return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
		} catch (InvalidKeySpecException ex) {
			throw new Exception(ex.getMessage());
		}
	}

	/**
	 * * 加密 *
	 * 
	 * @param key
	 *            加密的密钥 *
	 * @param data
	 *            待加密的明文数据 *
	 * @return 加密后的数据 *
	 * @throws Exception
	 */
	public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			cipher.init(Cipher.ENCRYPT_MODE, pk);
			int blockSize = cipher.getBlockSize();// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024
			// 加密块大小为127
			// byte,加密后为128个byte;因此共有2个加密块,第一个127
			// byte第二个为1个byte
			int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小
			int leavedSize = data.length % blockSize;
			int blocksSize = leavedSize != 0 ? data.length / blockSize + 1
					: data.length / blockSize;
			byte[] raw = new byte[outputSize * blocksSize];
			int i = 0;
			while (data.length - i * blockSize > 0) {
				if (data.length - i * blockSize > blockSize)
					cipher.doFinal(data, i * blockSize, blockSize, raw, i
							* outputSize);
				else
					cipher.doFinal(data, i * blockSize, data.length - i
							* blockSize, raw, i * outputSize);
				// 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到
				// ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了
				// OutputSize所以只好用dofinal方法。

				i++;
			}
			return raw;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * * 解密 *
	 * 
	 * @param key
	 *            解密的密钥 *
	 * @param raw
	 *            已经加密的数据 *
	 * @return 解密后的明文 *
	 * @throws Exception
	 */
	public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			cipher.init(cipher.DECRYPT_MODE, pk);
			int blockSize = cipher.getBlockSize();
			ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
			int j = 0;

			while (raw.length - j * blockSize > 0) {
				bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
				j++;
			}
			return bout.toByteArray();
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * * *
	 * 
	 * @param args
	 *            *
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		/*RSAPublicKey rsap = (RSAPublicKey) RSAUtil.generateKeyPair()
				.getPublic();
		rsap.getModulus();
		rsap.getPublicExponent();
		String test = "hello world";
		byte[] en_test = encrypt(getKeyPair().getPublic(), test.getBytes());
		byte[] de_test = decrypt(getKeyPair().getPrivate(), en_test);
		System.out.println(new String(de_test));*/
		
		/*RSAPublicKey pubk = RSAUtil.generateRSAPublicKey("108368048788890560576572359774440094528241439236977435842254047613639902146619552188260903793435066711695213909830538008019609061114995118579433741950108897670960853465900185040198867356782389765444400474968011359678815704914512251924472572119499063342297571073597918012349131762728165202050464377633235643721".getBytes(), "10001".getBytes());
		RSAPrivateKey prik = RSAUtil.generateRSAPrivateKey("108368048788890560576572359774440094528241439236977435842254047613639902146619552188260903793435066711695213909830538008019609061114995118579433741950108897670960853465900185040198867356782389765444400474968011359678815704914512251924472572119499063342297571073597918012349131762728165202050464377633235643721".getBytes(), "247dfc60927b0343ddce035402291f3fa2eb155188a99da7b92a2a7f3e92d9ac2c98e9949adb376ed4e1d2594f874bc28c34b965bde555a9fc08cda3a01730f5b1e7c6aed9022ecd3d8bdda36dbb0b8a50a1d06660eafdd497883d95c683f44be484fdd1782c6c0094ed3a7584e260e663311ed90d4aa0a16b6a4360fcd7cee1".getBytes());
		byte[] en_test = RSAUtil.encrypt(pubk, "abc".getBytes());
		byte[] de_test = RSAUtil.decrypt(prik, en_test);
		System.out.println(new String(de_test));*/
		
		/*RSAPublicKey rsap = (RSAPublicKey) RSAUtil.generateKeyPair().getPublic();
		System.out.println(rsap.toString());
		System.out.println(rsap.toString());
		System.out.println(rsap.getModulus());
		System.out.println(rsap.getPublicExponent());*/
	}
}


二、页面端代码

<script type="text/javascript" src="js/RSA.js"></script>
<script type="text/javascript" src="js/BigInt.js"></script>
<script type="text/javascript" src="js/Barrett.js"></script>

<script type="text/javascript">
/* <![CDATA[ */
var key ;
function loginformsubmit() {
	 bodyRSA();
	 var result = encryptedString(key, document.getElementById("tlogin_password").value);
	 document.getElementById("login_password").value = result;
	 return true;
}

function bodyRSA()
{
	setMaxDigits(130);
  var PublicExponent = "10001";
  var modulus = "9a523bbbfa1fb4b0d6beea7e4ef9484d1aa2bbfbc42091ad9a716c25274dccc20b04b112bb2e959088fa0ded359ccee455c1238b0100f792d11537adfbe0d746ec13a8bb9c9321f8e408910c8afabf7ba89de6c5d500e39fec69a85bd072e5e5ad18d0642d599737ec2532af5ef9f08f63ecaac1941ac3abe1dcbcc49f6dad49";
  	key = new RSAKeyPair("10001","","9a523bbbfa1fb4b0d6beea7e4ef9484d1aa2bbfbc42091ad9a716c25274dccc20b04b112bb2e959088fa0ded359ccee455c1238b0100f792d11537adfbe0d746ec13a8bb9c9321f8e408910c8afabf7ba89de6c5d500e39fec69a85bd072e5e5ad18d0642d599737ec2532af5ef9f08f63ecaac1941ac3abe1dcbcc49f6dad49"); 
  //页面端只需要更改PublicExponent和modulus 的值即可。
}
/* ]]> */
</script>


三、后台进行解密

String login_password = request.getParameter("login_password");
		try {
			byte[] en_result;
			byte[] de_result;
			StringBuffer sb;
			en_result = new BigInteger(login_password, 16).toByteArray();
			//System.out.println("RSAUtil.getKeyPair().getPrivate(): " + RSAUtil.getKeyPair().getPrivate());
			de_result = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(), en_result);
			sb = new StringBuffer().append(new String(de_result));
			login_password = sb.reverse().toString();
		} catch (Exception e) {
			//e.printStackTrace();
			log.error("rsa rsa Encryption failed", e);
		}


四、附上js脚本
1.Barrett.js
2.RSA.js
3.BigInt.js
  • js.rar (6.4 KB)
  • 下载次数: 391
分享到:
评论
1 楼 menzi_love 2009-11-19  
# public static KeyPair getKeyPair() throws Exception { 
#         String file = "D:/Java/eLibrary/config/RSAKey";//ConfigurationManager.getProperty(ConstrtsProperty.RSAFILE); 
#         FileInputStream fis = new FileInputStream(file); 
#         ObjectInputStream oos = new ObjectInputStream(fis); 
#         KeyPair kp = (KeyPair) oos.readObject(); 
#         oos.close(); 
#         fis.close(); 
#         return kp; 
#     } 

不知道 D:/Java/eLibrary/config/RSAKey 是什么,我测试报找不到文件。这个是生成的还是?

相关推荐

    RSA通过javascript加密java解密

    RSA算法是一种非对称加密算法,它基于两个不同的密钥:公钥和...综上所述,"RSA通过javascript加密java解密"是一个涉及客户端与服务器间安全通信的典型应用场景,通过非对称加密技术确保了数据在传输过程中的安全性。

    RSA非对称 C#解密、js加密实现登陆密文传输

    RSA非对称加密算法在IT领域中被广泛用于安全通信,特别是在登录系统中,它能够确保用户信息的安全传输。在给定的上下文中,我们看到一个C#和JavaScript结合的应用,用于实现登录过程中的密码加密和解密。下面将详细...

    java_RSA2048加密解密.zip

    后端,Java作为一种常用的企业级开发语言,拥有丰富的安全库,例如Bouncy Castle,用于处理RSA加密解密。Java代码可能使用了`java.security`包下的`KeyPairGenerator`、`PublicKey`、`PrivateKey`等类来生成和管理...

    rsa非对称加密,内含三个前端能用的加解密js

    `security.js`可能是一个包含RSA加密和解密功能的JavaScript库,可能提供了一种在前端实现RSA加解密的方法。在Web应用中,这种库常用于在用户与服务器之间安全地传输敏感数据,如登录凭证、信用卡信息等。`security....

    RSA 使用java 和javascript进行加解密

    RSA算法是一种非对称加密算法,它基于两个大素数的乘积,分别称为公钥和私钥。在加解密过程中,数据使用公钥加密,然后使用私钥解密,反之亦然。这种机制使得只有拥有私钥的人才能解密信息,保障了数据的安全性。在...

    RSA加密解密之javascript与java配套源码.zip

    RSA加密解密是一种广泛应用于网络安全领域的非对称加密技术,由Ron Rivest、Adi Shamir和Leonard Adleman三位科学家在1977年提出,因此得名RSA。这种加密方法基于大数因子分解的困难性,使得只有持有私钥的人才能...

    javascript与java进行RSA加密与解密

    JavaScript 和 Java 之间的 RSA 加密与解密是跨平台数据安全传输的重要技术。...通过以上步骤和库的使用,JavaScript 和 Java 之间可以实现安全的 RSA 加密解密交互,确保在数据传输过程中的隐私和安全。

    5.Java+js RSA非对称加密.rar

    本案例中,"5.Java+js RSA非对称加密.rar"是一个压缩包,包含了使用Java和JavaScript实现RSA非对称加密的代码示例。下面将详细解释相关知识点。 1. **非对称加密**: 非对称加密与对称加密不同,它使用一对公钥和...

    RSA非对称加密前端加密后端解密

    在实际应用中,RSA非对称加密还常常与哈希和盐值结合使用,进一步增强安全性。哈希可以将任意长度的输入转化为固定长度的输出,而盐值则可以防止针对特定数据的预计算攻击(如彩虹表)。这样,即使攻击者获取了加密...

    RSA非对称加密的RSA.zip

    本压缩包"RSA非对称加密的RSA.zip"包含的资源可能是用于实现RSA加密的Java库(jar包)和JavaScript文件,这些文件可以帮助开发者在他们的应用程序中集成RSA加密功能。"RSA"这个文件名可能是指包含密钥生成、加密和...

    JavaScript_RSA加解密+分段加解密.zip

    使用RSA非对称加密完成JavaScript前端RSA加密和分段加解密,最近研究了RSA非对称加密,关于什么是RSA,网上各种文章一搜一大把,但是关于如何使用RSA完成前端的组合加密解密,东西就非常少了,并且由于RSA的特性,一...

    用javascript与java进行RSA加密与解密

    在这个场景中,【标题】"用javascript与java进行RSA加密与解密" 提到的技术是使用JavaScript和Java来实现RSA加密算法,这是一种非对称加密方法,常用于保护敏感数据,如用户密码。以下是关于RSA加密和解密以及相关...

    前端使用jsencrypt加密后端使用java RSA解密功能实现源码

    本文将详细介绍一个实际案例:如何在前端使用JavaScript库`jsencrypt`进行RSA加密,并在后端使用Java进行解密。这个功能实现的核心知识点包括RSA算法、`jsencrypt`库的使用以及前后端的交互。 首先,RSA是一种非...

    javascript加密java解密

    - 解密过程:使用Java的Cipher类,结合预先配置好的密钥,进行解密操作。如果使用非对称加密,需要匹配的私钥。 3. **安全性考虑**: - 密钥管理:密钥的安全存储至关重要。不应将密钥硬编码在代码中,而应使用...

    Js Java Rsa 加密解密

    JavaScript、Java和RSA加密解密是信息安全领域中的关键技术,它们被广泛应用于数据传输、用户认证、Web应用安全等场景。RSA是一种非对称加密算法,以其发明者Ron Rivest、Adi Shamir和Leonard Adleman的名字命名,它...

    rsa前端加密,java后台解密

    这些文件对于理解并实现RSA加密解密的具体步骤至关重要。 总之,RSA加密技术为Web应用提供了安全的数据传输手段,确保了用户数据在互联网上的隐私和安全。在实际开发中,我们需要根据项目的具体需求,合理选择密钥...

    Java RSA加密前后端实现

    Java RSA加密技术是一种广泛应用于网络通信安全中的非对称加密算法,主要特点是公钥和私钥成对出现,其中公钥用于加密,私钥用于解密。这种加密方式的安全性较高,因为即使加密数据被截获,没有相应的私钥也无法解密...

    可以互操作的Java和Javascript RSA加密解密程序

    在“可以互操作的Java和Javascript RSA加密解密程序”中,我们看到这种技术被巧妙地应用于Java和JavaScript两个不同的编程环境中,实现跨平台的加密解密互操作。 首先,我们需要理解RSA算法的基本原理。RSA基于大数...

    RSA前台加密java后台解密项目

    RSA是一种非对称加密...前端使用JavaScript实现RSA加密,后端使用Java进行解密,两者的配合确保了数据的机密性。在实际开发中,还需要考虑密钥管理、错误处理和性能优化等多个方面,以确保整个系统的安全性和稳定性。

Global site tag (gtag.js) - Google Analytics