前端node-rsa公钥私钥生成工具加密 java私钥解密有没有做过的

5537人阅读
JS客户端RSA加密,Java服务端解密
阿影 发布于 日 16时, 15评/7967阅
分享到 新浪微博腾讯微博收藏+41踩顶0
在客户端浏览器,Javascript使用RSA算法,以公钥对密码进行加密,服务端使用相应的私钥进行解密。一般用于注册时或登录时填写的密码。&
Java引用到的包:&
commons-lang&
bouncycastle&
commons-codec&
commons-io&
标签: Bouncy Castle RSA JavaScript Java Bouncy Castle
代码片段(3)[全屏查看所有代码]
1. [文件] security.js ~ 19KB & & 下载(1449) & &&
2. [文件] RSAUtils.java ~ 15KB & & 下载(943) & &&
package my.tools.
import java.io.F
import java.io.FileInputS
import java.io.FileOutputS
import java.io.ObjectInputS
import java.io.ObjectOutputS
import java.math.BigI
import java.security.KeyP
import java.security.KeyF
import java.security.KeyPairG
import java.security.P
import java.security.PublicK
import java.security.PrivateK
import java.security.SecureR
import java.security.NoSuchAlgorithmE
import java.security.InvalidParameterE
import java.security.interfaces.RSAPublicK
import java.security.interfaces.RSAPrivateK
import java.security.spec.RSAPublicKeyS
import java.security.spec.RSAPrivateKeyS
import java.security.spec.InvalidKeySpecE
import javax.crypto.C
import mons.io.IOU
import mons.io.FileU
import mons.codec.DecoderE
import mons.codec.binary.H
import org.bouncycastle.jce.provider.BouncyCastleP
import org.slf4j.L
import org.slf4j.LoggerF
import mons.lang.StringU
import mons.lang.time.DateFormatU
&* RSA算法加密/解密工具类。
&* @author fuchun
&* @version 1.0.0,
public abstract class RSAUtils {
& & private static final Logger LOGGER = LoggerFactory.getLogger(RSAUtils.class);
& & /** 算法名称 */
& & private static final String ALGORITHOM = &RSA&;
& & /**保存生成的密钥对的文件名称。 */
& & private static final String RSA_PAIR_FILENAME = &/__RSA_PAIR.txt&;
& & /** 密钥大小 */
& & private static final int KEY_SIZE = 1024;
& & /** 默认的安全服务提供者 */
& & private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();
& & private static KeyPairGenerator keyPairGen =
& & private static KeyFactory keyFactory =
& & /** 缓存的密钥对。 */
& & private static KeyPair oneKeyPair =
& & private static File rsaPairFile =
& & static {
& & & & try {
& & & & & & keyPairGen = KeyPairGenerator.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
& & & & & & keyFactory = KeyFactory.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
& & & & } catch (NoSuchAlgorithmException ex) {
& & & & & & LOGGER.error(ex.getMessage());
& & & & rsaPairFile = new File(getRSAPairFilePath());
& & private RSAUtils() {
& & &* 生成并返回RSA密钥对。
& & private static synchronized KeyPair generateKeyPair() {
& & & & try {
& & & & & & keyPairGen.initialize(KEY_SIZE, newSecureRandom(DateFormatUtils.format(&yyyyMMdd&).getBytes()));
& & & & & & oneKeyPair = keyPairGen.generateKeyPair();
& & & & & & saveKeyPair(oneKeyPair);
& & & & & & return oneKeyP
& & & & } catch (InvalidParameterException ex) {
& & & & & & LOGGER.error(&KeyPairGenerator does not support a key length of & + KEY_SIZE + &.&, ex);
& & & & } catch (NullPointerException ex) {
& & & & & & LOGGER.error(&RSAUtils#KEY_PAIR_GEN is null, can not generate KeyPairGenerator instance.&,
& & & & & & & & & & ex);
& & &* 返回生成/读取的密钥对文件的路径。
& & private static String getRSAPairFilePath() {
& & & & String urlPath = RSAUtils.class.getResource(&/&).getPath();
& & & & return (new File(urlPath).getParent() + RSA_PAIR_FILENAME);
& & &* 若需要创建新的密钥对文件,则返回 {@code true},否则 {@code false}。
& & private static boolean isCreateKeyPairFile() {
& & & & // 是否创建新的密钥对文件
& & & & boolean createNewKeyPair =
& & & & if (!rsaPairFile.exists() || rsaPairFile.isDirectory()) {
& & & & & & createNewKeyPair =
& & & & return createNewKeyP
& & &* 将指定的RSA密钥对以文件形式保存。
& & &* @param keyPair 要保存的密钥对。
& & private static void saveKeyPair(KeyPair keyPair) {
& & & & FileOutputStream fos =
& & & & ObjectOutputStream oos =
& & & & try {
& & & & & & fos = FileUtils.openOutputStream(rsaPairFile);
& & & & & & oos = new ObjectOutputStream(fos);
& & & & & & oos.writeObject(keyPair);
& & & & } catch (Exception ex) {
& & & & & & ex.printStackTrace();
& & & & } finally {
& & & & & & IOUtils.closeQuietly(oos);
& & & & & & IOUtils.closeQuietly(fos);
& & &* 返回RSA密钥对。
& & public static KeyPair getKeyPair() {
& & & & // 首先判断是否需要重新生成新的密钥对文件
& & & & if (isCreateKeyPairFile()) {
& & & & & & // 直接强制生成密钥对文件,并存入缓存。
& & & & & & return generateKeyPair();
& & & & if (oneKeyPair != null) {
& & & & & & return oneKeyP
& & & & return readKeyPair();
& & // 同步读出保存的密钥对
& & private static KeyPair readKeyPair() {
& & & & FileInputStream fis =
& & & & ObjectInputStream ois =
& & & & try {
& & & & & & fis = FileUtils.openInputStream(rsaPairFile);
& & & & & & ois = new ObjectInputStream(fis);
& & & & & & oneKeyPair = (KeyPair) ois.readObject();
& & & & & & return oneKeyP
& & & & } catch (Exception ex) {
& & & & & & ex.printStackTrace();
& & & & } finally {
& & & & & & IOUtils.closeQuietly(ois);
& & & & & & IOUtils.closeQuietly(fis);
& & &* 根据给定的系数和专用指数构造一个RSA专用的公钥对象。
& & &* @param modulus 系数。
& & &* @param publicExponent 专用指数。
& & &* @return RSA专用公钥对象。
& & public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) {
& & & & RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger(modulus),
& & & & & & & & new BigInteger(publicExponent));
& & & & try {
& & & & & & return (RSAPublicKey) keyFactory.generatePublic(publicKeySpec);
& & & & } catch (InvalidKeySpecException ex) {
& & & & & & LOGGER.error(&RSAPublicKeySpec is unavailable.&, ex);
& & & & } catch (NullPointerException ex) {
& & & & & & LOGGER.error(&RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.&, ex);
& & &* 根据给定的系数和专用指数构造一个RSA专用的私钥对象。
& & &* @param modulus 系数。
& & &* @param privateExponent 专用指数。
& & &* @return RSA专用私钥对象。
& & public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) {
& & & & RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(newBigInteger(modulus),
& & & & & & & & new BigInteger(privateExponent));
& & & & try {
& & & & & & return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
& & & & } catch (InvalidKeySpecException ex) {
& & & & & & LOGGER.error(&RSAPrivateKeySpec is unavailable.&, ex);
& & & & } catch (NullPointerException ex) {
& & & & & & LOGGER.error(&RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.&, ex);
& & &* 根据给定的16进制系数和专用指数字符串构造一个RSA专用的私钥对象。
& & &* @param modulus 系数。
& & &* @param privateExponent 专用指数。
& & &* @return RSA专用私钥对象。
& & public static RSAPrivateKey getRSAPrivateKey(String hexModulus, String hexPrivateExponent) {
& & & & if(StringUtils.isBlank(hexModulus) || StringUtils.isBlank(hexPrivateExponent)) {
& & & & & & if(LOGGER.isDebugEnabled()) {
& & & & & & & & LOGGER.debug(&hexModulus and hexPrivateExponent cannot be empty. RSAPrivateKey value is null to return.&);
& & & & & & }
& & & & & &
& & & & byte[] modulus =
& & & & byte[] privateExponent =
& & & & try {
& & & & & & modulus = Hex.decodeHex(hexModulus.toCharArray());
& & & & & & privateExponent = Hex.decodeHex(hexPrivateExponent.toCharArray());
& & & & } catch(DecoderException ex) {
& & & & & & LOGGER.error(&hexModulus or hexPrivateExponent value is invalid. return null(RSAPrivateKey).&);
& & & & if(modulus != null && privateExponent != null) {
& & & & & & return generateRSAPrivateKey(modulus, privateExponent);
& & &* 根据给定的16进制系数和专用指数字符串构造一个RSA专用的公钥对象。
& & &* @param modulus 系数。
& & &* @param publicExponent 专用指数。
& & &* @return RSA专用公钥对象。
& & public static RSAPublicKey getRSAPublidKey(String hexModulus, String hexPublicExponent) {
& & & & if(StringUtils.isBlank(hexModulus) || StringUtils.isBlank(hexPublicExponent)) {
& & & & & & if(LOGGER.isDebugEnabled()) {
& & & & & & & & LOGGER.debug(&hexModulus and hexPublicExponent cannot be empty. return null(RSAPublicKey).&);
& & & & & & }
& & & & & &
& & & & byte[] modulus =
& & & & byte[] publicExponent =
& & & & try {
& & & & & & modulus = Hex.decodeHex(hexModulus.toCharArray());
& & & & & & publicExponent = Hex.decodeHex(hexPublicExponent.toCharArray());
& & & & } catch(DecoderException ex) {
& & & & & & LOGGER.error(&hexModulus or hexPublicExponent value is invalid. return null(RSAPublicKey).&);
& & & & if(modulus != null && publicExponent != null) {
& & & & & & return generateRSAPublicKey(modulus, publicExponent);
& & &* 使用指定的公钥加密数据。
& & &* @param publicKey 给定的公钥。
& & &* @param data 要加密的数据。
& & &* @return 加密后的数据。
& & public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {
& & & & Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
& & & & ci.init(Cipher.ENCRYPT_MODE, publicKey);
& & & & return ci.doFinal(data);
& & &* 使用指定的私钥解密数据。
& & &* @param privateKey 给定的私钥。
& & &* @param data 要解密的数据。
& & &* @return 原数据。
& & public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {
& & & & Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
& & & & ci.init(Cipher.DECRYPT_MODE, privateKey);
& & & & return ci.doFinal(data);
& & &* 使用给定的公钥加密给定的字符串。
& & &* &p /&
& & &* 若 {@code publicKey} 为 {@code null},或者 {@code plaintext} 为 {@code null} 则返回 {@code
& & &* null}。
& & &* @param publicKey 给定的公钥。
& & &* @param plaintext 字符串。
& & &* @return 给定字符串的密文。
& & public static String encryptString(PublicKey publicKey, String plaintext) {
& & & & if (publicKey == null || plaintext == null) {
& & & & & &
& & & & byte[] data = plaintext.getBytes();
& & & & try {
& & & & & & byte[] en_data = encrypt(publicKey, data);
& & & & & & return new String(Hex.encodeHex(en_data));
& & & & } catch (Exception ex) {
& & & & & & LOGGER.error(ex.getCause().getMessage());
& & &* 使用默认的公钥加密给定的字符串。
& & &* &p /&
& & &* 若{@code plaintext} 为 {@code null} 则返回 {@code null}。
& & &* @param plaintext 字符串。
& & &* @return 给定字符串的密文。
& & public static String encryptString(String plaintext) {
& & & & if(plaintext == null) {
& & & & & &
& & & & byte[] data = plaintext.getBytes();
& & & & KeyPair keyPair = getKeyPair();
& & & & try {
& & & & & & byte[] en_data = encrypt((RSAPublicKey)keyPair.getPublic(), data);
& & & & & & return new String(Hex.encodeHex(en_data));
& & & & } catch(NullPointerException ex) {
& & & & & & LOGGER.error(&keyPair cannot be null.&);
& & & & } catch(Exception ex) {
& & & & & & LOGGER.error(ex.getCause().getMessage());
& & &* 使用给定的私钥解密给定的字符串。
& & &* &p /&
& & &* 若私钥为 {@code null},或者 {@code encrypttext} 为 {@code null}或空字符串则返回 {@code null}。
& & &* 私钥不匹配时,返回 {@code null}。
& & &* @param privateKey 给定的私钥。
& & &* @param encrypttext 密文。
& & &* @return 原文字符串。
& & public static String decryptString(PrivateKey privateKey, String encrypttext) {
& & & & if (privateKey == null || StringUtils.isBlank(encrypttext)) {
& & & & & &
& & & & try {
& & & & & & byte[] en_data = Hex.decodeHex(encrypttext.toCharArray());
& & & & & & byte[] data = decrypt(privateKey, en_data);
& & & & & & return new String(data);
& & & & } catch (Exception ex) {
& & & & & & LOGGER.error(String.format(&\&%s\& Decryption failed. Cause: %s&, encrypttext, ex.getCause().getMessage()));
& & &* 使用默认的私钥解密给定的字符串。
& & &* &p /&
& & &* 若{@code encrypttext} 为 {@code null}或空字符串则返回 {@code null}。
& & &* 私钥不匹配时,返回 {@code null}。
& & &* @param encrypttext 密文。
& & &* @return 原文字符串。
& & public static String decryptString(String encrypttext) {
& & & & if(StringUtils.isBlank(encrypttext)) {
& & & & & &
& & & & KeyPair keyPair = getKeyPair();
& & & & try {
& & & & & & byte[] en_data = Hex.decodeHex(encrypttext.toCharArray());
& & & & & & byte[] data = decrypt((RSAPrivateKey)keyPair.getPrivate(), en_data);
& & & & & & return new String(data);
& & & & } catch(NullPointerException ex) {
& & & & & & LOGGER.error(&keyPair cannot be null.&);
& & & & } catch (Exception ex) {
& & & & & & LOGGER.error(String.format(&\&%s\& Decryption failed. Cause: %s&, encrypttext, ex.getMessage()));
& & &* 使用默认的私钥解密由JS加密(使用此类提供的公钥加密)的字符串。
& & &* @param encrypttext 密文。
& & &* @return {@code encrypttext} 的原文字符串。
& & public static String decryptStringByJs(String encrypttext) {
& & & & String text = decryptString(encrypttext);
& & & & if(text == null) {
& & & & & &
& & & & return StringUtils.reverse(text);
& & /** 返回已初始化的默认的公钥。*/
& & public static RSAPublicKey getDefaultPublicKey() {
& & & & KeyPair keyPair = getKeyPair();
& & & & if(keyPair != null) {
& & & & & & return (RSAPublicKey)keyPair.getPublic();
& & /** 返回已初始化的默认的私钥。*/
& & public static RSAPrivateKey getDefaultPrivateKey() {
& & & & KeyPair keyPair = getKeyPair();
& & & & if(keyPair != null) {
& & & & & & return (RSAPrivateKey)keyPair.getPrivate();
3. [代码][Java]代码 & &&
// Struts2 Action方法中:
// 将公钥的 modulus 和 exponent 传给页面。
// Hex -& apache commons-codec
RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();
& & & & & & ActionContext.getContext().put(&modulus&, newString(Hex.encodeHex(publicKey.getModulus().toByteArray())));
& & & & & & ActionContext.getContext().put(&exponent&, newString(Hex.encodeHex(publicKey.getPublicExponent().toByteArray())));
// 页面里,Javascript对明文进行加密:
var modulus = $('#hid_modulus').val(), exponent = $('#hid_exponent').val();
var key = RSAUtils.getKeyPair(exponent, '', modulus);
pwd1 = RSAUtils.encryptedString(key, pwd1);
pwd2 = RSAUtils.encryptedString(key, pwd2);
// 服务器端,使用RSAUtils工具类对密文进行解密
RSAUtils.decryptStringByJs(password1);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1490814次
积分:15519
积分:15519
排名:第674名
原创:263篇
转载:431篇
评论:221条
(1)(7)(8)(8)(8)(3)(2)(11)(2)(5)(6)(1)(4)(25)(21)(12)(12)(16)(6)(22)(33)(20)(31)(10)(4)(5)(19)(10)(4)(14)(16)(10)(24)(8)(63)(19)(25)(22)(44)(13)(7)(15)(15)(22)(14)(41)(11)&>&&>&&>&&>&RSA加密解密(JS加密JAVA解密)
RSA加密解密(JS加密JAVA解密)
上传大小:1.3MB
RSA非对称加密,指定一个密码种子,使用该密码种子用java生成密钥对,并把公钥分发到客户端(浏览器),保存密码种子;JS采用公钥对重要信息进行加密,然后传回后台,取出密码种子重新生成密码对,使用私钥对密文进行解密。要保证密码对的安全就必须保证密码种子的不可预知性。
综合评分:4.1(18位用户评分)
所需积分:1
下载次数:77
审核通过送C币
创建者:mttsui
创建者:cpongo1
创建者:f_feng3
课程推荐相关知识库
上传者其他资源上传者专辑
开发技术热门标签
VIP会员动态
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
CSDN&vip年卡&4000万程序员的必选
RSA加密解密(JS加密JAVA解密)
会员到期时间:剩余下载次数:
积分不足!
资源所需积分
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分
当前拥有积分
VIP年卡全年1200次免积分下载
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:加解密(16)
详细内容:/question/
你只要想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6705973次
积分:59385
积分:59385
排名:第40名
原创:247篇
转载:2584篇
评论:637条
(90)(17)(25)(37)(63)(7)(74)(67)(95)(177)(114)(86)(40)(43)(71)(14)(10)(17)(12)(6)(20)(27)(54)(71)(97)(74)(32)(2)(24)(21)(62)(60)(36)(23)(27)(46)(34)(76)(63)(121)(141)(74)(54)(120)(77)(42)(4)(12)(19)(1)(9)(15)(19)(18)(16)(31)(79)(68)24750人阅读
编程交流(167)
C++ 、C#(79)
Unix/Linux(11)
企业架构(18)
随笔(46)
技术文章(211)
JavaScript(12)
原文地址:&通常我们做一个Web应用程序的时候都需要登录,登录就要输入用户名和登录密码,并且,用户名和登录密码都是明文传输的,这样就有可能在中途被别人拦截,尤其是在网吧等场合。这里顺带一个小插曲,我以前有家公司,办公室装修时候安排的网口相对较少,不太够用,于是我和另外一个同事使用了一个hub来共享一个网口,这就导致了很有趣的现象:任何他的网络包我都能抓得到,当然了,我的他也能抓得到。这是不是有很大的安全隐患了?我有可能在不经意间会泄漏自己的密码。所以,很多安全要求较高的网站都不会明文传输密码,它们会使用https来确保传输过程的安全,https是用证书来实现的,证书来自于证书颁发机构,当然了,你也可以自己造一张证书,但这样别人访问你的网站的时候还是会遇到麻烦,因为你自己造的证书不在用户浏览器的信任范围之内,你还得在用户浏览器上安装你的证书,来让用户浏览器相信你的网站,很多用户并不知道如何操作,就算会操作,也能也不乐意干;另一种选择是你向权威证书颁发机构申请一张证书,但这样有一定的门槛,还需要付费,也不是我们乐意干的事。所以,我打算自己实现一个密码加密传输方法。这里使用了RSA非对称加密算法,对称加密也许大家都已经很熟悉,也就是加密和解密用的都是同样的密钥,没有密钥,就无法解密,这是对称加密。而非对称加密算法中,加密所用的密钥和解密所用的密钥是不相同的:你使用我的公钥加密,我使用我的私钥来解密;如果你不使用我的公钥加密,那我无法解密;如果我没有私钥,我也没法解密。我设计的这个登录密码加密传输方法的原理图如下:&首先,先演练一下非对称加密:static void Main(string[] args){
//用于字符串和byte[]之间的互转
UTF8Encoding utf8encoder = new UTF8Encoding();
//产生一对公钥私钥
RSACryptoServiceProvider rsaKeyGenerator = new RSACryptoServiceProvider(1024);
string publickey = rsaKeyGenerator.ToXmlString(false);
string privatekey = rsaKeyGenerator.ToXmlString(true);
//使用公钥加密密码
RSACryptoServiceProvider rsaToEncrypt = new RSACryptoServiceProvider();
rsaToEncrypt.FromXmlString(publickey);
string strPassword = &@123#abc$&;
Console.WriteLine(&The original password is: {0}&, strPassword);
byte[] byEncrypted = rsaToEncrypt.Encrypt(utf8encoder.GetBytes(strPassword), false);
Console.Write(&Encoded bytes: &);
foreach (Byte b in byEncrypted)
Console.Write(&{0}&, b.ToString(&X&));
Console.Write(&\n&);
Console.WriteLine(&The encrypted code length is: {0}&, byEncrypted.Length);
RSACryptoServiceProvider rsaToDecrypt = new RSACryptoServiceProvider();
rsaToDecrypt.FromXmlString(privatekey);
byte[] byDecrypted = rsaToDecrypt.Decrypt(byEncrypted, false);
string strDecryptedPwd = utf8encoder.GetString(byDecrypted);
Console.WriteLine(&Decrypted Password is: {0}&, strDecryptedPwd);}大家可以清楚看到,密码被加密成128字节长度的密文,为什么是固定128字节呢?这是因为我们的RSACryptoServiceProvider默认生成的key的长度是1024,即1024位的加密,所以不管你要加密的密码有多长,它生成的密文的长度肯定是128字节,也因为这样,密码的长度是有限制的,1024位的RSA算法,只能加密大约100个字节长度的明文,要提高可加密的明文的长度限制,就得增加key的长度,比如把key改到2048位,这样能加密的明文的长度限制也就变为大概200出头这样……还是太少啊!而且这样会带来加密速度的显著下降,RSA本来就很慢……是的,比同没有长度限制的对称加密,这种非对称加密的限制可真多,即便是200个字符,又能传输什么东西呢?——密码!这个就够了,传输完密码之后,我们就使用对称加密,所以,RSA往往是用来“协商”一个对称加密的key的。接下去,真正的难点在于用javascript实现一个和.net的RSA兼容的算法。密码学,对我来说真像天书一般,每次我一看就头大,这个工作是没办法自己做的了,只能到网上找,那是相当的费力啊,找到许多js的RSA实现,但都和.net的这套东西不兼容,最后还是功夫不负有心人,终于找到了一套。不多说,上代码:&html xmlns=&http://www.w3.org/1999/xhtml&&&head runat=&server&&
&title&RSA Login Test&/title&
&script src=&Scripts/jquery-1.4.1.js& type=&text/javascript&&&/script&
&script src=&Scripts/jQuery.md5.js& type=&text/javascript& &&/script&
&script src=&Scripts/BigInt.js& type=&text/javascript&&&/script&
&script src=&Scripts/RSA.js& type=&text/javascript&&&/script&
&script src=&Scripts/Barrett.js& type=&text/javascript&&&/script&
&script type=&text/javascript&&
function cmdEncrypt() {
setMaxDigits(129);
var key = new RSAKeyPair(&&%=strPublicKeyExponent%&&, &&, &&%=strPublicKeyModulus%&&);
var pwdMD5Twice = $.md5($.md5($(&#txtPassword&).attr(&value&)));
var pwdRtn = encryptedString(key, pwdMD5Twice);
$(&#encrypted_pwd&).attr(&value&, pwdRtn);
$(&#formLogin&).submit();
&/script&&/head&&body&
&form action=&Default.aspx& id=&formLogin& method=&post&&
User Name:
&input id=&txtUserName& name=&txtUserName& value=&&%=postbackUserName%&& type=&text& maxlength=&16& /&
&input id=&txtPassword& type=&password& maxlength=&16& /&
&input id=&btnLogin& type=&button& value=&Login& onclick=&return cmdEncrypt()& /&
&input type=&hidden& name=&encrypted_pwd& id=&encrypted_pwd& /&
&%=LoginResult%&
&/div&&/body&&/html&这是客户端代码,大家可以看到,基本没有什么服务器端代码,&%=postbackUserName%&用于回显输入的用户名,&%=LoginResult%&用于显示登录结果,&%=strPublicKeyExponent%&和&%=strPublicKeyModulus%&则用来告诉客户端RSA公钥。需要的javascript文件说明:jQuery.md5.js -& 用于对密码进行两次md5加密;(我通常在数据库中保存的用户密码是两次MD5后的结果)BigInt.js - 用于生成一个大整型;(这是RSA算法的需要)RSA.js - RSA的主要算法;Barrett.js - RSA算法所需要用到的一个支持文件;对于密码学,我几乎一无所知,所以没办法跟大家解释清楚RSA算法的原理,抱歉,我只知道怎么用。关于javascript中这行代码:“setMaxDigits(129);”具体表示什么我也不清楚,我只知道,把参数改为小于129的数之后会导致客户端的javascript执行进入死循环。服务器端代码也很简单:protected void Page_Load(object sender, EventArgs e){
LoginResult = &&;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
if (string.Compare(Request.RequestType, &get&, true)==0)
//将私钥存Session中
Session[&private_key&] = rsa.ToXmlString(true);
bool bLoginSucceed = false;
string strUserName = Request.Form[&txtUserName&];
postbackUserName = strUserN
string strPwdToDecrypt = Request.Form[&encrypted_pwd&];
rsa.FromXmlString((string)Session[&private_key&]);
byte[] result = rsa.Decrypt(HexStringToBytes(strPwdToDecrypt), false);
System.Text.ASCIIEncoding enc = new ASCIIEncoding();
string strPwdMD5 = enc.GetString(result);
if (string.Compare(strUserName, &user1&, true)==0 && string.Compare(strPwdMD5, &14e1b600b1fd579fd85291&, true)==0)
bLoginSucceed = true;
catch (Exception)
if (bLoginSucceed)
LoginResult = &登录成功&;
LoginResult = &登录失败&;
//把公钥适当转换,准备发往客户端
RSAParameters parameter = rsa.ExportParameters(true);
strPublicKeyExponent = BytesToHexString(parameter.Exponent);
strPublicKeyModulus = BytesToHexString(parameter.Modulus);}用户名“user1”密码“123456”登录成功!抓取http报文看看POST的“密码”:这样的“密码”的破解就成为了理论上的可行了。:)下面提供完整代码下载(使用VS2010开发环境):
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1205926次
积分:14911
积分:14911
排名:第738名
原创:302篇
转载:180篇
评论:380条
(9)(4)(1)(12)(4)(3)(5)(10)(5)(1)(4)(5)(11)(3)(5)(25)(19)(3)(10)(23)(21)(16)(2)(3)(6)(3)(2)(2)(1)(6)(2)(5)(1)(1)(2)(1)(5)(2)(5)(1)(1)(3)(5)(1)(4)(3)(1)(4)(3)(7)(9)(2)(2)(2)(4)(2)(7)(10)(1)(19)(13)(3)(10)(7)(7)(1)(9)(8)(7)(3)(7)(6)(7)(3)(5)(3)(8)(16)(28)

我要回帖

更多关于 rsa 公钥 私钥 长度 的文章

 

随机推荐