javascript rsa java,用javascript与java执行 RSA加密与解密

用javascript与java执行

RSA加密与解密

2009-12-12 14:58:30   出处:https://www.yqdown.com

这几天一直做安全登录,网上查了好多资料,不尽如意。

具体实现思路如下:

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

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

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

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

这其中有一个关键是处理

服务端的公钥,传入客户端,客户端用此公钥加密字符串后,后又能在服务端用私钥解出。

此文即为实现此步而作。

加密算法为RSA:

1。服务端的RSA  java实现

/**     *     */    package com.sunsoft.struts.util;

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;

/**     * 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{            FileInputStream fis = new FileInputStream("C:/RSAKey.txt");             ObjectInputStream oos = new ObjectInputStream(fis);             KeyPair kp= (KeyPair) oos.readObject();             oos.close();             fis.close();             return kp;        }

public static void saveKeyPair(KeyPair kp)throws Exception{

FileOutputStream fos = new FileOutputStream("C:/RSAKey.txt");             ObjectOutputStream oos = new ObjectOutputStream(fos);             //生成密钥             oos.writeObject(kp);             oos.close();             fos.close();        }

/**         * * 生成公钥 *         *         * @param modulus *         * @param publicExp

onent *         * @return RSAPublicKey *         * @throws Exception         */        public static RSAPublicKey generateRSAPublicKey(byte[] modulus,                byte[] publicExp

onent) 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(publicExp

onent));            try {                return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);            } catch (InvalidKeySpecException ex) {                throw new Exception(ex.getMessage());            }        }

/**         * * 生成私钥 *         *         * @param modulus *         * @param privateExp

onent *         * @return RSAPrivateKey *         * @throws Exception         */        public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,                byte[] privateExp

onent) 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(privateExp

onent));            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();            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));        }    }

/**     *     */    package com.sunsoft.struts.util;

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;

/**     * 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{            FileInputStream fis = new FileInputStream("C:/RSAKey.txt");             ObjectInputStream oos = new ObjectInputStream(fis);             KeyPair kp= (KeyPair) oos.readObject();             oos.close();             fis.close();             return kp;        }

public static void saveKeyPair(KeyPair kp)throws Exception{

FileOutputStream fos = new FileOutputStream("C:/RSAKey.txt");             ObjectOutputStream oos = new ObjectOutputStream(fos);             //生成密钥             oos.writeObject(kp);             oos.close();             fos.close();        }

/**         * * 生成公钥 *         *         * @param modulus *         * @param publicExp

onent *         * @return RSAPublicKey *         * @throws Exception         */        public static RSAPublicKey generateRSAPublicKey(byte[] modulus,                byte[] publicExp

onent) 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(publicExp

onent));            try {                return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);            } catch (InvalidKeySpecException ex) {                throw new Exception(ex.getMessage());            }        }

/**         * * 生成私钥 *         *         * @param modulus *         * @param privateExp

onent *         * @return RSAPrivateKey *         * @throws Exception         */        public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,                byte[] privateExp

onent) 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(privateExp

onent));            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();            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));        }    }

2.测试页面:

IndexAction.java

/*     * Generated by MyEclipse Struts     * Template path: templates/java/JavaClass.vtl     */    package com.sunsoft.struts.action;

import java.security.interfaces.RSAPrivateKey;    import java.security.interfaces.RSAPublicKey;

import javax.servlet.http.HttpServletRequest;    import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;    import org.apache.struts.action.ActionForm;    import org.apache.struts.action.ActionForward;    import org.apache.struts.action.ActionMapping;

import com.sunsoft.struts.util.RSAUtil;

/**     * MyEclipse Struts     * Creation date: 06-28-2008     *     * XDoclet definition:     * @struts.action validate="true"     */    public class IndexAction extends Action {        /*         * Generated Methods         */

/**         * Method execute         * @param mapping         * @param form         * @param request         * @param response         * @return ActionForward         */        public ActionForward execute(ActionMapping mapping, ActionForm form,                HttpServletRequest request, HttpServletResponse response)throws Exception {

RSAPublicKey rsap = (RSAPublicKey) RSAUtil.getKeyPair().getPublic();            String module = rsap.getModulus().toString(16);            String empoent = rsap.getPublicExp

onent().toString(16);            System.out.println("module");            System.out.println(module);            System.out.println("empoent");            System.out.println(empoent);            request.setAttribute("m", module);            request.setAttribute("e", empoent);            return mapping.findForward("login");        }    }

/*     * Generated by MyEclipse Struts     * Template path: templates/java/JavaClass.vtl     */    package com.sunsoft.struts.action;

import java.security.interfaces.RSAPrivateKey;    import java.security.interfaces.RSAPublicKey;

import javax.servlet.http.HttpServletRequest;    import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;    import org.apache.struts.action.ActionForm;    import org.apache.struts.action.ActionForward;    import org.apache.struts.action.ActionMapping;

import com.sunsoft.struts.util.RSAUtil;

/**     * MyEclipse Struts     * Creation date: 06-28-2008     *     * XDoclet definition:     * @struts.action validate="true"     */    public class IndexAction extends Action {        /*         * Generated Methods         */

/**         * Method execute         * @param mapping         * @param form         * @param request         * @param response         * @return ActionForward         */        public ActionForward execute(ActionMapping mapping, ActionForm form,                HttpServletRequest request, HttpServletResponse response)throws Exception {

RSAPublicKey rsap = (RSAPublicKey) RSAUtil.getKeyPair().getPublic();            String module = rsap.getModulus().toString(16);            String empoent = rsap.getPublicExp

onent().toString(16);            system.out.println("module");            system.out.println(module);            system.out.println("empoent");            system.out.println(empoent);            request.setAttribute("m", module);            request.setAttribute("e", empoent);            return mapping.findForward("login");        }    }

通过此action进入登录页面,并传入公钥的 Modulus 与PublicExp

onent的hex编码形式。

3。登录页面 login.jsp

login

                                                       

}

     

         
Login:
Password:
                  login

                                                       

}

     

         
Login:
Password:
                 

/*     * Generated by MyEclipse Struts     * Template path: templates/java/JavaClass.vtl     */    package com.sunsoft.struts.action;

import java.math.BigInteger;

import javax.servlet.http.HttpServletRequest;    import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;    import org.apache.struts.action.ActionForm;    import org.apache.struts.action.ActionForward;    import org.apache.struts.action.ActionMapping;

import com.sunsoft.struts.util.RSAUtil;

/**     * MyEclipse Struts     * Creation date: 06-28-2008     *     * XDoclet definition:     * @struts.action path="/login" name="loginForm" input="/login.jsp" scope="request" validate="true"     * @struts.action-forward name="error" path="/error.jsp"     * @struts.action-forward name="success" path="/success.jsp"     */    public class LoginAction extends Action {        /*         * Generated Methods         */

/**         * Method execute         * @param mapping         * @param form         * @param request         * @param response         * @return ActionForward         */        public ActionForward execute(ActionMapping mapping, ActionForm form,                HttpServletRequest request, HttpServletResponse response) throws Exception{            //LoginForm loginForm = (LoginForm) form;            String result = request.getParameter("result");            System.out.println("原文加密后为:");            System.out.println(result);            byte[] en_result = new BigInteger(result, 16).toByteArray();            System.out.println("转成byte[]"+new String(en_result));            byte[] de_result = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),en_result);            System.out.println("还原密文:");

System.out.println(new String(de_result));            StringBuffer sb = new StringBuffer();            sb.append(new String(de_result));            System.out.println(sb.reverse().toString());            return mapping.findForward("success");        }    }

/*     * Generated by MyEclipse Struts     * Template path: templates/java/JavaClass.vtl     */    package com.sunsoft.struts.action;

import java.math.BigInteger;

import javax.servlet.http.HttpServletRequest;    import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;    import org.apache.struts.action.ActionForm;    import org.apache.struts.action.ActionForward;    import org.apache.struts.action.ActionMapping;

import com.sunsoft.struts.util.RSAUtil;

/**     * MyEclipse Struts     * Creation date: 06-28-2008     *     * XDoclet definition:     * @struts.action path="/login" name="loginForm" input="/login.jsp" scope="request" validate="true"     * @struts.action-forward name="error" path="/error.jsp"     * @struts.action-forward name="success" path="/success.jsp"     */    public class LoginAction extends Action {        /*         * Generated Methods         */

/**         * Method execute         * @param mapping         * @param form         * @param request         * @param response         * @return ActionForward         */        public ActionForward execute(ActionMapping mapping, ActionForm form,                HttpServletRequest request, HttpServletResponse response) throws Exception{            //LoginForm loginForm = (LoginForm) form;            String result = request.getParameter("result");            system.out.println("原文加密后为:");            system.out.println(result);            byte[] en_result = new BigInteger(result, 16).toByteArray();            system.out.println("转成byte[]"+new String(en_result));            byte[] de_result = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),en_result);            system.out.println("还原密文:");

system.out.println(new String(de_result));            StringBuffer sb = new StringBuffer();            sb.append(new String(de_result));            system.out.println(sb.reverse().toString());            return mapping.findForward("success");        }    }

分享到

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值