千家信息网

RSA加密算法的简单案例

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,RSA加密算法是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码***。那关于RSA加密算法有哪些应用呢?以下举一个数据库身份验证的案例。在使用数据集进行身份认证时,密码存在数据库
千家信息网最后更新 2026年11月01日RSA加密算法的简单案例

RSA加密算法是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码***。

那关于RSA加密算法有哪些应用呢?以下举一个数据库身份验证的案例。

在使用数据集进行身份认证时,密码存在数据库中,认证时用户输入的密码与数据库中密码相同则认证通过,若数据库被破解了则对系统造成威胁,怎样保证系统安全呢?这里就可以应用RSA加密算法,对权限加密。

思路:

就是在url中传用户名密码时,先把用户名进行翻转,然后再进行加密,如输入的密码为12,实际后台进行加密的值为21,再与数据库进行验证,这样就可以避免数据库被破解查看到的是21的加密码,登陆系统时以21是无法登陆成功的。

以报表软件FineReport为例,这是一个能读取各类数据库的报表软件,分客户端和前端展示。

实现方案:

1、把RSA加密使用的第三方包,放到工程web-inf/lib文件夹下即可。

2、调用js文件

RSA文件夹为前端js加密时需要调用js文件,因此需要将Barrett.js、BigInt.js、RSA.js放到工程目录下如:WebReport/js,新建js文件夹放入js文件。

3、定义RSA加密类

定义RSAUtil.java类文件,先运行类中generateKeyPair()方法,会在服务器D盘中生成一个随机的RSAKey.txt文件,保存公钥和密钥,每访问一次这个方法会刷新一次txt文件。

package com.fr.privilege;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 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();                String test = "hello world";                byte[] en_test = encrypt(getKeyPair().getPublic(), test.getBytes());                System.out.println("123:" + new String(en_test));                byte[] de_test = decrypt(getKeyPair().getPrivate(), en_test);                System.out.println(new String(de_test));        }}

4、定义密码验证类

定义TestPasswordValidatorRSA.java密码验证类

定义一个类,命名为TestPasswordValidatorRSA.java,扩展于AbstractPasswordValidator,重写其中密码验证方法encodePassword,先把输入的密码进行翻转,然后再进行加密,返回密码进行验证,具体代码如下:

package com.fr.privilege;  import com.fr.privilege.providers.dao.AbstractPasswordValidator;  public class TestPasswordValidatorRSA extends AbstractPasswordValidator{      //@Override    public String encodePassword( String clinetPassword) {            try {                    //对密码进行翻转如输入ab翻转后为ba                    StringBuffer sb = new StringBuffer();                  sb.append(new String(clinetPassword));                String bb = sb.reverse().toString();                    //进行加密                    byte[] en_test = RSAUtil.encrypt(RSAUtil.getKeyPair().getPublic(),bb.getBytes());                                   //进行解密,如果数据库里面保存的是加密码,则此处不需要进行解密                    byte[] de_test = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),en_test);                      //返回加密密码                    clinetPassword=new String(de_test);                                } catch (Exception e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                }                return clinetPassword; //即获取加密密码再与数据库密码匹配。      }        @Override        public boolean validatePassword(String arg0, String arg1) {                // TODO Auto-generated method stub                return false;        }}

5、编译类文件

首先编译RSAUtil.java类文件在服务器的D盘生成RSAKey.txt文件,再编译TestPasswordValidatorRSA.java类,把编译后的class文件放到项目工程web-inf/classes/com/fr/privilege文件夹中。

6、登陆Login.jsp页面设置

客户端请求到登录页面,随机生成一字符串,此随机字符串作为密钥加密密码,如下代码:

<%@page contentType="text/html" pageEncoding="UTF-8"%><%@page import="com.fr.privilege.providers.dao.RSAUtil"%><%!public String Testmo() {                String module = "";                try {                        java.security.interfaces.RSAPublicKey rsap = (java.security.interfaces.RSAPublicKey) RSAUtil                                        .getKeyPair().getPublic();                        module = rsap.getModulus().toString(16);                } catch (Exception e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                }                return module;        }%><%!public String Testem() {                String empoent = "";                try {                        java.security.interfaces.RSAPublicKey rsap = (java.security.interfaces.RSAPublicKey) RSAUtil                                        .getKeyPair().getPublic();                        empoent = rsap.getPublicExponent().toString(16);                } catch (Exception e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                }                return empoent;        }%>                                                                                                                        

请登录

用户名:

密 码:

加密 密码 数据 文件 数据库 生成 密钥 用户 方法 用户名 认证 输入 验证 大小 算法 文件夹 编译 公钥 工程 报表 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州大一互联网络科技有限公司 互联网科技工作委员会毛军 没上市的科技互联网公司 天津摩尔互联网科技 互联网金融科技平台 兼蜜互联网科技 互联网科技公司名称 互联网科技创新企业排名 银川新华互联网科技学校地址 安控科技rtu产品工业互联网 互联网科技公司需要的职位 深圳国际航运科技和互联网 创业天下互联网科技有限公司 燊美集互联网科技有限公司 乌鲁木齐新华智原互联网科技学校 宇信科技在杭州互联网排第几 图游互联网科技 广州有谷有贝互联网科技有限公司 网互联网络科技 每日互联网科技新闻 金融科技创新监管互联网金融 互联网科技的发展 百单互联网科技有限公司 丰台科技园 互联网 济南和联互联网科技有限公司 玖二柒互联网科技公司待遇 科技与互联网的利与弊 中国科技互联网公司收入 迪庆互联网科技招生 兰石爱特工业互联网科技分公司
0