Java下几种加密方式的实现

最近一直在做这方面的东西,先把实现放着,原理慢慢补。

Maven库

因为jdk本身的加解密算法并不完整,所以需要添加以下两个库的支持。

	<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.46</version>
        </dependency>

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

AES

一种可逆的算法,原文可以通过一组密钥被加密,然后通过这个密钥被还原回来。

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;

public class AESCoder {

    public static final String KEY_ALGORITHM = "AES";

    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    //转换密钥
    private static Key toKey(byte[] key) throws Exception{
        //实例化DES的材料
        SecretKey secretKey = new SecretKeySpec(key,KEY_ALGORITHM);
        return secretKey;
    }

    //解密
    public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
        //还原密钥
        Key k = toKey(key);
        //实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //初始化,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE,k);
        //执行操作
        return cipher.doFinal(data);
    }

    //加密
    public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
        //还原密钥
        Key k = toKey(key);

        //实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE,k);
        //执行操作
        return cipher.doFinal(data);
    }

    //生成密钥
    public static byte[] initKey() throws Exception{

        //实例化
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);

        //要求密钥长度为256
        kg.init(256);

        //生成秘密密钥
        SecretKey secretKey = kg.generateKey();

        //获得秘密密钥
        return secretKey.getEncoded();
    }

    public static void main(String args[]) throws Exception{

        String str = "AES" ;

        byte[] inputData = str.getBytes();

        System.out.println("原文:"+str);

        //初始化密钥
        byte[] key = AESCoder.initKey();

        System.out.println("密钥:"+ Base64.encodeBase64String(key));

        //加密
        inputData = AESCoder.encrypt(inputData,key);
        System.out.println("加密后:"+ new String(Hex.encode(inputData)));

        //解密
        byte[] outputData = AESCoder.decrypt(inputData,key);

        String outstr = new String(outputData);

        System.out.println(outstr);
    }

}

SHA

一组不可逆的hash算法,基于MD4演变而来。

import org.bouncycastle.util.encoders.Hex;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHACoder {
    //SHA-256加密算法
    public static byte[] encodeSHA(byte[] data){
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            return md.digest(data);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
    //输出16进制的哈希值
    public static String encodeSHAHex(byte[] data){
        byte[] b = encodeSHA(data);
        return new String(Hex.encode(b));
    }
}

RSA

一种非对称加密方式,密钥有两个二进制数据,一个作为公钥,一个作为私钥,二进制的数据可以被其中一个密钥加密,然后通过另外一个密钥解密。

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSACoder {

    public static final String KEY_ALGORITHM = "RSA";

    //公钥名称
    private static final String PUBLIC_KEY = "RSAPublicKey";
    //私钥名称
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    //RSA密钥长度
    //默认是1024
    //密钥长度必须在64位
    //范围在512 ~ 65536之间
    private static final int KEY_SIZE = 1024 ;

    //私钥解密
    public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{
        //取得私钥
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //生成私钥
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.DECRYPT_MODE,privateKey);

        return cipher.doFinal(data);
    }

    //公钥解密
    public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{
        //取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //生成公钥
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);

        //对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.DECRYPT_MODE,publicKey);
        return cipher.doFinal(data);
    }

    //私钥加密
    public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{
        //取得私钥
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //生成私钥
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.ENCRYPT_MODE,privateKey);

        return cipher.doFinal(data);
    }

    //公钥加密
    public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
        //取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        //生成公钥
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);

        //对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.ENCRYPT_MODE,publicKey);

        return cipher.doFinal(data);
    }

    //取得私钥
    public static byte[] getPriavteKey(Map<String,Object> keymap) throws Exception{
        Key key = (Key)keymap.get(PRIVATE_KEY);

        return key.getEncoded();
    }

    //取得公钥
    public static byte[] getPublicKey(Map<String,Object> keymap) throws Exception {
        Key key = (Key)keymap.get(PUBLIC_KEY);

        return key.getEncoded();
    }

    //初始化密钥
    public static Map<String,Object> initKey() throws Exception{
        //实例化密钥对生成
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);

        //初始化密钥对生成器
        keyPairGen.initialize(KEY_SIZE);

        //生成密钥对
        KeyPair keyPair = keyPairGen.generateKeyPair();

        //公钥
        RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();

        //私钥
        RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();

        //封装密钥
        Map<String,Object> keyMap = new HashMap<>(2);

        keyMap.put(PUBLIC_KEY,publicKey);
        keyMap.put(PRIVATE_KEY,privateKey);

        return keyMap;
    }

    public static void main(String args[]) throws Exception{
        //初始化密钥
        Map<String,Object> keymap = RSACoder.initKey();

        byte[] publickey = RSACoder.getPublicKey(keymap);
        byte[] privatekey = RSACoder.getPriavteKey(keymap);

        System.out.println(Base64.encodeBase64String(publickey));
        System.out.println(Base64.encodeBase64String(privatekey));

        //校验

        //私钥加密,公钥解密
        String inputstr = "whthomas";
        //加密
        byte[] encodedeData1 = RSACoder.encryptByPrivateKey(inputstr.getBytes(),privatekey);
        System.out.println(Base64.encodeBase64String(encodedeData1));

        //解密
        byte[] decodedeData1 = RSACoder.decryptByPublicKey(encodedeData1,publickey);
        System.out.println(new String(decodedeData1));

        //公钥加密,私钥解密
        //加密
        byte[] encodedeData2 = RSACoder.encryptByPublicKey(inputstr.getBytes(), publickey);
        System.out.println(Base64.encodeBase64String(encodedeData2));
        //解密
        byte[] decodedeData2 = RSACoder.decryptByPrivateKey(encodedeData2, privatekey);
        System.out.println(new String(decodedeData2));
    }
}

可能会出现的错误

加解密过程中可能会出现这种错误

Caused by: java.security.InvalidKeyException: Illegal key size or default parameters

这是由于一些法律法规的限制,jdk源码包中减弱的加密的强度。

解决这个问题可以从Oracle网站上下载一个压缩文件

将这个包解压,把里面的两个jar包:local_policy.jar 和 US_export_policy.jar 替换掉原来Java安装目录{JAVA_HOME}/jre/lib/security 下的两个jar包接就可以了。

你可能感兴趣的:(java)