JAVA数据加密

Posted l_learning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA数据加密相关的知识,希望对你有一定的参考价值。

网站发生数据泄露事故,影响都是非常大的,为防范数据泄露事故,通常做法是对敏感信息进行加密处理。
加密算法可以归结为三大类:哈希算法、对称加密算法、非对称加密算法

1. 哈希算法

哈希算法中最著名的当属MD5算法,MD5算法生成的信息摘要只有128位,数据加密后是不可逆的,常用来加密用户密码

String ha = "U001_pay_10_key";
String encryptStr = DigestUtils.md5DigestAsHex(ha.getBytes());
System.out.println(encryptStr);

2.对称加密算法

最为流行的对称加密算法是AES算法,对称算法的好处是加密解密的效率比较高。对称算法的缺点是不够安全。对称加密算法密钥是相同的,只要密钥泄露出去,通信的密文就会被破解。

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class AESUtils 

    /**
     * 算法/加密模式/填充方式
     */
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    /**
     * AES 加密、解密秘钥长度需为16
     */
    private static final int SECURITY_KEY_LEN = 16;

    private static final String ALGORITHM = "AES";
    public final static String UTF8 = "utf-8";

    /**
     * AES加密
     * @param source 加密字符串
     * @param secretKey 密钥
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws UnsupportedEncodingException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public static String encrypt(String source, String secretKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException 
        verifyParam(source, secretKey);
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secretKey.getBytes(), ALGORITHM));
        // base64 编码加密内容
        return Base64.encodeBase64String(cipher.doFinal(source.getBytes(UTF8)));
    

    /**
     * AES解密
     * @param source 解密字符串
     * @param secretKey 密钥s
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws UnsupportedEncodingException
     */
    public static String decrypt(String source, String secretKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException 
        verifyParam(source, secretKey);
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey.getBytes(), ALGORITHM));
        // base64解密
        byte[] encrypted = Base64.decodeBase64(source);
        return new String(cipher.doFinal(encrypted), UTF8);
    

    public static void verifyParam(String source, String secretKey) throws InvalidKeyException 
        if (StringUtils.isAllBlank(source, secretKey)) 
            throw new IllegalArgumentException("suurce and secretKey cannot be empty");
        
        if(secretKey.getBytes().length != SECURITY_KEY_LEN)
            throw new InvalidKeyException("AES key length is not 16 bytes");
        
    


3.非对称加密算法

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。非对称加密中存在一对密钥,一个叫做公钥,一个叫做私钥。在加密解密的过程中,可以使用公钥加密明文,私钥解密密文;也可以私钥加密明文,公钥解密密文。

非对称算法的在应用的过程, 通常用公钥加密,私钥解密;私钥签名,公钥验签
1.接收方生成公钥和私钥,公钥公开,私钥保留;
2.发送方将要发送的消息采用公钥加密,得到密文,然后将密文发送给接收方;
3.接收方收到密文后,用自己的私钥进行解密,获得明文。

package com.example.demo.common.crypto;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSAUtils 

    private static Logger log = LoggerFactory.getLogger(RSAUtils.class);

    private static final String ALGORITHM = "RSA";

    private static final int RSA_KEY_SIZE = 1024;

    public final static String UTF8 = "utf-8";

    public static final String PUBLIC_KEY = "public_key";

    public static final String PRIVATE_KEY = "private_key";

    /**
     * 生成公钥和私钥
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static Map<String, String> generateRasKey() throws NoSuchAlgorithmException, UnsupportedEncodingException 
        Map<String, String> rsa = new HashMap<>();
        // KeyPairGenerator 类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = null;
        keyPairGen = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGen.initialize(RSA_KEY_SIZE, new SecureRandom());
        // 生成一个密钥对,保存在 keyPair 中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到私钥和公钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()), UTF8);
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())), UTF8);
        // 将公钥和私钥保存到 Map
        rsa.put(PUBLIC_KEY, publicKeyString);
        rsa.put(PRIVATE_KEY, privateKeyString);
        return rsa;
    

    /**
     * 公钥加密
     * @param source 加密字符串
     * @param publicKey 公钥
     * @return
     */
    public static String encrypt(String source, String publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException 
        // base64 编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(decoded));
        // RSA 加密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encodeBase64String(cipher.doFinal(source.getBytes(UTF8)));
    

    /**
     * 私钥解密
     * @param source 解密字符串
     * @param privateKey 私钥
     * @return
     */
    public static String decrypt(String source, String privateKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
        // base64 编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
        // RSA 解密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        //64位解码加密后的字符串
        byte[] encrypted = Base64.decodeBase64(source);
        return new String(cipher.doFinal(encrypted), UTF8);
    

    /**
     * 私钥签名
     * @param source 加密字符串
     * @param privateKey 私钥
     * @return
     */
    public static String sign(String source, String privateKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
        // base64 编码的公钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
        // RSA 加密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, priKey);
        return Base64.encodeBase64String(cipher.doFinal(source.getBytes(UTF8)));
    

    /**
     * 公钥验签
     * @param source 解密字符串
     * @param publicKey 公钥
     * @return
     */
    public static String verify(String source, String publicKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException 
        // base64 解码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(decoded));
        // RSA 解密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        // base64 解码的公钥
        byte[] encrypted = Base64.decodeBase64(source);
        return new String(cipher.doFinal(encrypted), UTF8);
    



以上是关于JAVA数据加密的主要内容,如果未能解决你的问题,请参考以下文章

JAVA数据加密

JAVA数据加密

聊对称加密非对称加密Hash算法

java AES加密

Android使用RSA加密和解密

Java 加密解密的方法有哪些