美文网首页
Java安全编程:RSA加密解密

Java安全编程:RSA加密解密

作者: 张振伟 | 来源:发表于2018-06-07 10:59 被阅读28次

安全 RSA

/**
 * RSA算法加密解密例子
 * 注意:RSA加密对明文的长度是有限制的,RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行。
 * 
 */
public class RSACoder extends TestCase {

    /**
     * 测试用私钥加密再用公钥解密
     * 
     * @throws Exception
     */
    public void test1() throws Exception {
        byte[] arr = this.readFileIntoByteArr(new File("D:/data.txt"));
        System.out.println("加密前的明文:" + new String(arr, "GBK"));

        Map<String, Object> keyMap = this.initKey();
        PrivateKey priKey = (PrivateKey) keyMap.get("PrivateKey");
        PublicKey pubKey = (PublicKey) keyMap.get("PublicKey");

        byte[] encryptData = this.encryptByPriKey(arr, priKey.getEncoded());
        System.out.println("密文:" + Hex.encodeHexString(encryptData));

        byte[] data = this.decryptByPubKey(encryptData, pubKey.getEncoded());
        System.out.println("解密后的明文:" + new String(data, "GBK"));
    }

    /**
     * 测试数字签名与验签
     * 
     * @throws Exception
     */
    public void test2() throws Exception {
        byte[] arr = this.readFileIntoByteArr(new File("D:/data.txt"));
        System.out.println("签名主体:" + new String(arr, "GBK"));

        Map<String, Object> keyMap = this.initKey();
        PrivateKey priKey = (PrivateKey) keyMap.get("PrivateKey");
        PublicKey pubKey = (PublicKey) keyMap.get("PublicKey");

        byte[] sign = this.sign(arr, priKey.getEncoded());
        System.out.println("签名:" + Hex.encodeHexString(sign));

        boolean b = this.verify(arr, pubKey.getEncoded(), sign);
        System.out.println(b ? "验签成功" : "验签失败");
    }

    /**
     * 测试直接对主体签名与先对主体加摘要再签名得到的签名是不一样的。
     * 
     * @throws Exception
     */
    public void test3() throws Exception {
        byte[] arr = this.readFileIntoByteArr(new File("D:/data.txt"));
        System.out.println("签名主体:" + new String(arr, "GBK"));

        Map<String, Object> keyMap = this.initKey();
        PrivateKey priKey = (PrivateKey) keyMap.get("PrivateKey");
        PublicKey pubKey = (PublicKey) keyMap.get("PublicKey");
        // 直接签名
        byte[] sign1 = this.sign(arr, priKey.getEncoded());
        System.out.println("签名:" + Hex.encodeHexString(sign1));

        // 先得到MD5摘要再签名
        byte[] md5 = DigestUtils.md5(arr);
        byte[] sign2 = this.sign(md5, priKey.getEncoded());
        System.out.println("签名:" + Hex.encodeHexString(sign2));
    }

    /**
     * 生成密钥对
     * 
     * @return
     * @throws NoSuchAlgorithmException
     */
    public Map<String, Object> initKey() throws NoSuchAlgorithmException {
        // 实例化密钥对生成器
        KeyPairGenerator gener = KeyPairGenerator.getInstance("RSA");
        gener.initialize(1024);
        KeyPair pair = gener.generateKeyPair();
        PrivateKey priKey = pair.getPrivate();
        PublicKey pubKey = pair.getPublic();

        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put("PrivateKey", priKey);
        keyMap.put("PublicKey", pubKey);

        System.out.println("私钥:" + Hex.encodeHexString(priKey.getEncoded()));
        System.out.println("公钥:" + Hex.encodeHexString(pubKey.getEncoded()));

        return keyMap;
    }

    /**
     * 读取文件内容到byte数组
     * 
     * @param file
     * @return
     * @throws IOException
     */
    public byte[] readFileIntoByteArr(File file) throws IOException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try {
            FileInputStream in = new FileInputStream(file);
            byte[] tmpbuf = new byte[1024];
            int count = 0;
            while ((count = in.read(tmpbuf)) != -1) {
                bout.write(tmpbuf, 0, count);
                tmpbuf = new byte[1024];
            }
            in.close();
        } catch (FileNotFoundException e) {
            throw new FileNotFoundException("文件" + file.getPath() + "不存在");
        } catch (IOException e) {
            throw new IOException("读取文件内容到BYTE数组中出现IO异常", e);
        }
        return bout.toByteArray();
    }

    /**
     * 私钥加密
     * 
     * @param data
     * @param priKeyByte
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public byte[] encryptByPriKey(byte[] data, byte[] priKeyByte) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 获取私钥
        KeySpec spec = new PKCS8EncodedKeySpec(priKeyByte);
        // 生成私钥
        Key priKey = keyFactory.generatePrivate(spec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, priKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥解密
     * 
     * @param data
     * @param pubKeyByte
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public byte[] decryptByPubKey(byte[] data, byte[] pubKeyByte) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 获取公钥
        KeySpec spec = new X509EncodedKeySpec(pubKeyByte);
        // 生成公钥
        Key pubKey = keyFactory.generatePublic(spec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    /**
     * 使用MD5withRSA算法,加签
     * 
     * @param data
     * @param priKeyByte
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws InvalidKeyException
     * @throws SignatureException
     */
    public byte[] sign(byte[] data, byte[] priKeyByte) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 获取私钥
        KeySpec spec = new PKCS8EncodedKeySpec(priKeyByte);
        // 生成私钥
        PrivateKey priKey = keyFactory.generatePrivate(spec);

        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(priKey);
        signature.update(data);

        return signature.sign();
    }

    /**
     * 使用MD5withRSA算法,解签
     * 
     * @param data
     * @param pubKeyByte
     * @param sign
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws InvalidKeyException
     * @throws SignatureException
     */
    public boolean verify(byte[] data, byte[] pubKeyByte, byte[] sign) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
            SignatureException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 获取公钥
        KeySpec spec = new X509EncodedKeySpec(pubKeyByte);
        // 生成公钥
        PublicKey pubKey = keyFactory.generatePublic(spec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(pubKey);
        signature.update(data);
        return signature.verify(sign);
    }

}

相关文章

  • Java安全编程:RSA加密解密

    安全 RSA RSA是最常用非对称加密算法。常用于消息签名。它的加解密的密钥是成对出现的。使用私钥加密只能用对应的...

  • RSA加密方式

    RSA加密方式 获取RSA密钥 加密 解密 js库

  • 数据安全

    iOS客户端与JAVA服务器之间的RSA加密解密

  • kotlin版本RSA非对称加密解密与分段加密解密

    基于kotlin语言的RSA非对称加密解密与分段加密解密 RSA非对称加密 RSA非对称加密的具体算法与来源我就不...

  • java实现RSA非对称加密解密

    之前写过一篇java实现AES对称加密解密在对密码加密传输的场景下 RSA非对称加密解密可能会更加适合。原理就是后...

  • python操作RSA加密解密

    python操作RSA加密解密

  • Rsa加解密

    /*** Rsa 加解密* 用法:* (1)公钥加密,私钥解密* (2)私钥加密,公钥解密*/class ...

  • RSA加解密学习笔记

    RSA加解密简单说明: RSA是非对称加密方式,就是说加密解密不是同一个Key。私钥加密公钥解密,待加密的明文字节...

  • RSA加密

    RSA加密为非对称加密实现 对称加密:加密解密使用同一个算法 非对称加密:加密和解密使用不同算法 rsa加密原理 ...

  • 常用理解,RSA, 数字证书

    RSA算法的理解 1.RSA算法是目前最可靠的非对称加密算法,加密密钥和解密密钥不同,安全性比较高。2.RSA算法...

网友评论

      本文标题:Java安全编程:RSA加密解密

      本文链接:https://www.haomeiwen.com/subject/lcowsftx.html