数据加密的一些理解

24 篇文章 0 订阅

(一)加密算法分为:
(1)对称加密算法:

  • DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法,AES算法。

(2)非对称加密算法 :

  • RSA、Elgamal、背包算法、Rabin、D-H、ECC。

(3)哈希算法 :

  • MD2、MD4、MD5 和 SHA-1

(二) 区别及特点:
对称加密算法:

  • 秘钥只有一个,通过该秘钥可以对加密过后的数据进行解密。加密解密速度相对快,安全性低一点。解密加密都用同一个秘钥所以叫对称加密算法。

非对称加密算法 :

  • 一般分为两个秘钥 一个加密秘钥一个解密秘钥, 称为公钥和秘钥。
    公钥进行加密,可以公开。秘钥进行解密不公开。加密解密速度较慢一点。安全性高。两个秘钥不一样所以叫非对称加密算法 。

哈希算法 :

  • 目的是将任意长输入通过算法变为固定长输出,且保证输入变化一点输出都不同,且不能反向解密。

(三) 举例

对称加密算法 (AES):

/**
 * Created by linving on 2016/11/10.
 */

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;


/**
 * 编码工具类
 * 1.将byte[]转为各种进制的字符串
 * 2.base 64 encode
 * 3.base 64 decode
 * 4.获取byte[]的md5值
 * 5.获取字符串md5值
 * 6.结合base64实现md5加密
 * 7.AES加密
 * 8.AES加密为base 64 code
 * 9.AES解密
 * 10.将base 64 code AES解密
 *
 * @author uikoo9
 * @version 0.0.7.20140601
 */
public class AESUtil {


    /**
     * 将byte[]转为各种进制的字符串
     *
     * @param bytes byte[]
     * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
     * @return 转换后的字符串
     */
    public static String binary(byte[] bytes, int radix) {
        return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
    }

    /**
     * base 64 encode
     *
     * @param bytes 待编码的byte[]
     * @return 编码后的base 64 code
     */
    public static String base64Encode(byte[] bytes) {
        return new BASE64Encoder().encode(bytes);
    }

    /**
     * base 64 decode
     *
     * @param base64Code 待解码的base 64 code
     * @return 解码后的byte[]
     * @throws Exception
     */
    public static byte[] base64Decode(String base64Code) throws Exception {
        return new BASE64Decoder().decodeBuffer(base64Code);
    }

    /**
     * 获取byte[]的md5值
     *
     * @param bytes byte[]
     * @return md5
     * @throws Exception
     */
    public static byte[] md5(byte[] bytes) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(bytes);

        return md.digest();
    }

    /**
     * 获取字符串md5值
     *
     * @param msg
     * @return md5
     * @throws Exception
     */
    public static byte[] md5(String msg) throws Exception {
        return md5(msg.getBytes());
    }

    /**
     * 结合base64实现md5加密
     *
     * @param msg 待加密字符串
     * @return 获取md5后转为base64
     * @throws Exception
     */
    public static String md5Encrypt(String msg) throws Exception {
        return base64Encode(md5(msg));
    }

    /**
     * AES加密
     *
     * @param content    待加密的内容
     * @param encryptKey 加密密钥
     * @return 加密后的byte[]
     * @throws Exception
     */
    public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128, new SecureRandom(encryptKey.getBytes()));

        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));

        return cipher.doFinal(content.getBytes("utf-8"));
    }

    /**
     * AES加密为base 64 code
     *
     * @param content    待加密的内容
     * @param encryptKey 加密密钥
     * @return 加密后的base 64 code
     * @throws Exception
     */
    public static String aesEncrypt(String content, String encryptKey) {
        try {
            return base64Encode(aesEncryptToBytes(content, encryptKey));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * AES解密
     *
     * @param encryptBytes 待解密的byte[]
     * @param decryptKey   解密密钥
     * @return 解密后的String
     * @throws Exception
     */
    public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) {

        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(decryptKey.getBytes()));
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
            byte[] decryptBytes = cipher.doFinal(encryptBytes);
            return new String(decryptBytes);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将base 64 code AES解密
     *
     * @param encryptStr 待解密的base 64 code
     * @param decryptKey 解密密钥
     * @return 解密后的string
     * @throws Exception
     */
    public static String aesDecrypt(String encryptStr, String decryptKey)  {
        try {
            return aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

非对称加密算法(RSA)

/**
 * Created by linving on 2016/11/10.
 */

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
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.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;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * RSA算法,实现数据的加密解密。
 * @author ShaoJiang
 *
 */
public class RSAUtil {

    private static Cipher cipher;

    static{
        try {
            cipher = Cipher.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成密钥对
     * @return
     */
    public static Map<String,String> generateKeyPair(){
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            // 密钥位数
            keyPairGen.initialize(1024);
            // 密钥对
            KeyPair keyPair = keyPairGen.generateKeyPair();
            // 公钥
            PublicKey publicKey = keyPair.getPublic();
            // 私钥
            PrivateKey privateKey = keyPair.getPrivate();
            //得到公钥字符串
            String publicKeyString = getKeyString(publicKey);
            //得到私钥字符串
            String privateKeyString = getKeyString(privateKey);
            //将生成的密钥对返回
            Map<String,String> map = new HashMap<>();
            map.put("publicKey",publicKeyString);
            map.put("privateKey",privateKeyString);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 得到公钥
     *
     * @param key
     *            密钥字符串(经过base64编码)
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 得到私钥
     *
     * @param key
     *            密钥字符串(经过base64编码)
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    /**
     * 得到密钥字符串(经过base64编码)
     *
     * @return
     */
    public static String getKeyString(Key key) throws Exception {
        byte[] keyBytes = key.getEncoded();
        String s = (new BASE64Encoder()).encode(keyBytes);
        return s;
    }

    /**
     * 使用公钥对明文进行加密,返回BASE64编码的字符串
     * @param publicKey
     * @param plainText
     * @return
     */
    public static String encrypt(PublicKey publicKey,String plainText){
        try {
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] enBytes = cipher.doFinal(plainText.getBytes());
            return (new BASE64Encoder()).encode(enBytes);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用keystore对明文进行加密
     * @param
     * @param plainText      明文
     * @return
     */
    public static String encrypt(String publicKey,String plainText){
        try {
            cipher.init(Cipher.ENCRYPT_MODE,getPublicKey(publicKey));
            byte[] enBytes = cipher.doFinal(plainText.getBytes());
            return (new BASE64Encoder()).encode(enBytes);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用私钥对明文密文进行 解密
     * @param privateKey
     * @param enStr
     * @return
     */
    public static String decrypt(PrivateKey privateKey,String enStr){
        try {
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] deBytes = cipher.doFinal((new BASE64Decoder()).decodeBuffer(enStr));
            return new String(deBytes);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用keystore对密文进行解密
     * @param enStr   密文
     * @return
     */
    public static String decrypt(String privateKey,String enStr){
        try {
            cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKey));
            byte[] deBytes = cipher.doFinal((new BASE64Decoder()).decodeBuffer(enStr));
            return new String(deBytes);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

散列算法 /哈希算法(MD5 )

import java.io.IOException;
import java.io.StringReader;

public class HexDump {
    class HexTablifier {
        private int m_row = 8;

        private String m_pre = "";

        private String m_post = "\n";

        public HexTablifier() {
        }

        public HexTablifier(int row) {
            this(row, "", "\n");
        }

        public HexTablifier(int row, String pre) {
            this(row, pre, "\n");
        }

        public HexTablifier(int row, String pre, String post) {
            m_row = row;
            m_pre = pre;
            m_post = post;
        }

        public String format(String hex) {
            StringReader reader = new StringReader(hex);
            StringBuilder builder = new StringBuilder(hex.length() * 2);

            try {
                while (getHexLine(builder, reader)) {
                }
            } catch (IOException e) {
                // 不应该有异常出现。
            }

            return builder.toString();
        }

        private boolean getHexLine(StringBuilder builder, StringReader reader)
                throws IOException {
            StringBuilder lineBuilder = new StringBuilder();
            boolean result = true;

            for (int i = 0; i < m_row; i++) {
                result = getHexByte(lineBuilder, reader);

                if (result == false)
                    break;
            }

            if (lineBuilder.length() > 0) {
                builder.append(m_pre);
                builder.append(lineBuilder);
                builder.append(m_post);
            }

            return result;
        }

        private boolean getHexByte(StringBuilder builder, StringReader reader)
                throws IOException {
            char[] hexByte = new char[4];
            int bytesRead = reader.read(hexByte);

            if (bytesRead == -1)
                return false;

            builder.append(hexByte, 0, bytesRead);
            builder.append(" ");

            return bytesRead == 4;
        }
    }

    private static final char m_hexCodes[] = { '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    private static final int m_shifts[] = { 60, 56, 52, 48, 44, 40, 36, 32, 28,
            24, 20, 16, 12, 8, 4, 0 };

    public static String tablify(byte[] bytes) {
        return (new HexDump()).new HexTablifier().format(HexDump.toHex(bytes));
    }

    public static String tablify(byte[] bytes, int row) {
        return (new HexDump()).new HexTablifier(row).format(HexDump
                .toHex(bytes));
    }

    public static String tablify(byte[] bytes, int row, String pre) {
        return (new HexDump()).new HexTablifier(row, pre).format(HexDump
                .toHex(bytes));
    }

    public static String tablify(String hex, int row, String pre, String post) {
        return (new HexDump()).new HexTablifier(row, pre, post).format(hex);
    }

    private static String toHex(final long value, final int digitNum) {
        StringBuilder result = new StringBuilder(digitNum);

        for (int j = 0; j < digitNum; j++) {
            int index = (int) ((value >> m_shifts[j + (16 - digitNum)]) & 15);
            result.append(m_hexCodes[index]);
        }

        return result.toString();
    }

    public static String toHex(final byte value) {
        return toHex(value, 2);
    }

    public static String toHex(final short value) {
        return toHex(value, 4);
    }

    public static String toHex(final int value) {
        return toHex(value, 8);
    }

    public static String toHex(final long value) {
        return toHex(value, 16);
    }

    public static String toHex(final byte[] value) {
        return toHex(value, 0, value.length);
    }

    public static String toHex(final byte[] value, final int offset,
            final int length) {
        StringBuilder retVal = new StringBuilder();

        int end = offset + length;
        for (int x = offset; x < end; x++)
            retVal.append(toHex(value[x]));

        return retVal.toString();
    }

    public static byte[] restoreBytes(String hex) {
        byte[] bytes = new byte[hex.length() / 2];
        for (int i = 0; i < bytes.length; ++i) {
            int c1 = charToNumber(hex.charAt(2 * i));
            int c2 = charToNumber(hex.charAt(2 * i + 1));
            if (c1 == -1 || c2 == -1) {
                return null;
            }
            bytes[i] = (byte) ((c1 << 4) + c2);
        }

        return bytes;
    }

    private static int charToNumber(char c) {
        if (c >= '0' && c <= '9') {
            return c - '0';
        } else if (c >= 'a' && c <= 'f') {
            return c - 'a' + 0xa;
        } else if (c >= 'A' && c <= 'F') {
            return c - 'A' + 0xA;
        } else {
            return -1;
        }
    }
}
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;

/**
 * Created by linving on 2016/11/12.
 */
public class MD5Util {

    public static String getStringMD5(String value) {
        if (value == null || value.trim().length() < 1) {
            return null;
        }
        try {
            return getMD5(value.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static String getMD5(byte[] source) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            return HexDump.toHex(md5.digest(source));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

}

Test :

import java.util.Map;

/**
 * Created by linving on 2016/11/10.
 */
public class Test {
    public static void main(String[] args) {
        testRSA();
        testAES();
        tetsMD5();
    }

    private static void testAES() {


        String data = "adcb";
        System.out.println("AES加密前:" + data);

        String key = "123456";
        System.out.println("AES加密密钥和解密密钥:" + key);

        String encrypt = AESUtil.aesEncrypt(data, key);
        System.out.println("AES加密后:" + encrypt);

        String decrypt = AESUtil.aesDecrypt(encrypt, key);
        System.out.println("AES解密后:" + decrypt);

    }


    private static void testRSA() {

        String data = "adsbc";
        String publicKey = "";
        String privateKey = "";
        System.out.println("RSA原始数据: " + data);

        Map<String, String> keyPair = RSAUtil.generateKeyPair();
        publicKey = keyPair.get("publicKey");
        privateKey = keyPair.get("privateKey");
        System.out.println("RSA公钥: " + publicKey);
        System.out.println("RSA私钥: " + privateKey);

        String encryptData = RSAUtil.encrypt(publicKey, data);
        System.out.println("RSA加密数据: " + encryptData);
        String decryptData = RSAUtil.decrypt(privateKey, encryptData);
        System.out.println("RSA解密数据: " + decryptData);
    }

    private static void tetsMD5() {
        String data = "adsbc";
        System.out.println("MD5原始数据: " + data);
        String encryptData = MD5Util.getStringMD5(data);
        System.out.println("MD5 加密数据: " + encryptData);


    }

}


结果:

RSA原始数据: adsbc
RSA公钥: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwUnEo/9+NI8GJbQtwl6X7MuALqe7YzuDNEeGn
3zEuiktxbXj53duJoYtGqO+rY+Vae7Ypt7UwolgnFtfJbfSmoBJc7wuBPOdTFkpsb7nYZXTvNoFI
fYdjT2mQgcOnZGSoz7alApPQ1sxXkkZ2tx+H+hsSaHxTBHW1Pq6Eyqi8LQIDAQAB
RSA私钥: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALBScSj/340jwYltC3CXpfsy4Aup
7tjO4M0R4affMS6KS3FtePnd24mhi0ao76tj5Vp7tim3tTCiWCcW18lt9KagElzvC4E851MWSmxv
udhldO82gUh9h2NPaZCBw6dkZKjPtqUCk9DWzFeSRna3H4f6GxJofFMEdbU+roTKqLwtAgMBAAEC
gYEAjAquvfWcRKllihUFxQNtXTpnIFxzy9dkTPwq0f4/PcuxaAGe2DYRrBqWWCTNVr8c5uTjJfc2
/c2zXjiSYvXmHS8EGFglwsJ8Dos+FiPtWTJl0Xo3Qhnbs2+F2z9Idgg0ddzrLK5r2o6l8VWuv/43
vdrjnvc4ArF/Kas/RHKyzzECQQDlVI2aiAqkOjs44sxr2rrRZRcRp5qxz8k/M31yRJnHWEVL6DXx
9IxGtkZNYdaD6fHgfbxd/5Xano7iyxvoJGmjAkEAxNPEh1ZW8SFQaE9mt/AMU6OMDM6F399uunOs
7yzz6vCUxLOIko6oyFj0WiilQEr9Y1wr1EZGkcMHYeJFK1k/7wJANJqtlKnqDvvQg976Vy8oNUoD
/ae9g1YParDr8J8tyx1DYAMXBLY8yyeafruXklDCi+UrpUAwZqKCUiGW+CwKEwJBAMHiTMx3+0qp
41ftJyT3fF0DVJjk8zD1GlDmU6qCoH+EnzcoFtcvWgmIvqL1ONsdQ38Vs0L2OtuovuPoDPTHhNcC
QBkOkrgFhJYnmDDTMUj4TCEO64RIdOyzzpFeQ0TgpjMJ99QOv8Q2kEFpylCw9bYMk1uioCStYSR8
ZOhE+H2N+yg=
RSA加密数据: Olsmy/qEigtaXIhlY8g41ktk1pXo/Kr098hA0keGM718yc6vnS2Mzc0YFXCQUMnpYS3ZEa7mm0Lg
CBIQNaPC8LPRmVS+giXui5Us9vbtYmejSRC0aDqnFqlONaoQidxHGSow65vpvgPTTfm3Hec/xOnC
6iEaslW4bsaEQcTHm6k=
RSA解密数据: adsbc
AES加密前:adcb
AES加密密钥和解密密钥:123456
AES加密后:F0QsZk5pFhDME01ZT7sQ0Q==
AES解密后:adcb
MD5原始数据: adsbc
MD5 加密数据: 51d84a98aeb971d801a9e1bed8803bd1

Process finished with exit code 0

这就是常用的加密算法了, 通常如果数据比较隐私的话,会采用多重加密算法。比如先经过 RSA 再经过 AES 算法进行加密。

用RSA算法将AES的秘钥和数据绑定在一起,解密后拿到AES的秘钥再解密。

更多精彩内容:
http://jblog.top/

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值