zoukankan      html  css  js  c++  java
  • 数据加密小结(初级)

    越来越发现学过的东西不记下来,一段时间就忘得一干二净。

    以下为前段时间了解的数据加密的初级知识。

    加密的本质:通过算法,将有序可识别的字符串,转换成肉眼不可识别的字符串。

    分类:

    • 一.单向加密算法
    • 二.对称加密算法
    • 三.非对称加密算法

    一.单项加密算法

      加密过程不可逆 .

      BASE64 严格地说,属于编码格式,而非加密算法;

      MD5(Message Digest algorithm 5,信息摘要算法);

      SHA(Secure Hash Algorithm,安全散列算法);

      HMAC(hash message authentication code,散列消息鉴别码);

    SHA-1 与 MD5 的比较

        因为二者均由 MD4 导出,SHA-1 和 MD5 彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:

        对强行攻击的安全性

        最显著和最重要的区别是 SHA-1 摘要比 MD5 摘要长 32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对 MD5 是 2^128 数量级的操作,而对 SHA-1 则是 2^160 数量级的操作。这样,SHA-1 对强行攻击有更大的强度。

        对密码分析的安全性

        由于 MD5 的设计,易受密码分析的攻击,SHA-1 显得不易受这样的攻击。

        速度

        在相同的硬件上,SHA-1 的运行速度比 MD5 慢。

    base64DEMO:

    public class Base64Test {

    // 解密
    public static String getFromBase64(String s){
    byte[] b = null;
    String result = null;
    if (!Strings.isNullOrEmpty(s)) {
    BASE64Decoder decoder=new BASE64Decoder();
    try {
    b=decoder.decodeBuffer(s);
    result=new String(b,"utf-8");
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    return result;
    }
    // 加密
    public static String getBase64(String s){
    byte[] b = null;
    String result = null;
    try {
    b=s.getBytes("utf-8");
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    if (!Strings.isNullOrEmpty(s)) {
    result = new BASE64Encoder().encode(b);
    }
    return result;
    }

    public static void main(String [] args){
    System.out.println(getBase64("admin"));
    System.out.println(getFromBase64("YWRtaW4="));
    }
    }

    MD5 demo:

    public class Md5Test {
    public static String MD5(String s) {

    if(Strings.isNullOrEmpty(s)){
    return null;
    }
    char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    try {
    byte[] btInput = s.getBytes();
    // 获得MD5摘要算法的 MessageDigest 对象
    // MessageDigest mdInst = MessageDigest.getInstance("MD5");
    MessageDigest mdInst = MessageDigest.getInstance("SHA");
    // MessageDigest mdInst = MessageDigest.getInstance("SHA-1");
    // 使用指定的字节更新摘要
    mdInst.update(btInput);
    // 获得密文
    byte[] md = mdInst.digest();
    // 把密文转换成十六进制的字符串形式
    int j = md.length;
    char str[] = new char[j * 2];
    // 调用api将byte转成十六进制字符
    System.out.println( new String(new Hex().encode(md)));

    int k = 0;
    for (int i = 0; i < j; i++) {
    byte byte0 = md[i];
    // 定义转换成16进制的算法
    str[k++] = hexDigits[byte0 >>> 4 & 0xf];
    str[k++] = hexDigits[byte0 & 0xf];
    }
    return new String(str);
    } catch (Exception e) {
    e.printStackTrace();
    return null;
    }
    }
    public static void main(String[] args) {
    System.out.println(MD5("admin"));
    System.out.println(MD5("加密"));
    }
    }

    SHA demo:

    public class ShaTest {
    /**
    * 定义加密方式
    */
    private final static String KEY_SHA = "SHA";
    private final static String KEY_SHA1 = "SHA-1";
    private final static String KEY_SHA224 = "SHA-224";
    private final static String KEY_SHA256 = "SHA-256";
    /**
    * 全局数组
    */
    private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
    "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    /**
    * 构造函数
    */
    public ShaTest() {}

    /**
    * SHA 加密
    * @param data 需要加密的字符串
    * @return 加密之后的字符串
    * @throws Exception
    */
    public static String encryptSHA(String data) throws Exception {
    // 验证传入的字符串
    if (Strings.isNullOrEmpty(data)) {
    return "";
    }
    // 创建具有指定算法名称的信息摘要
    MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
    // 使用指定的字节数组对摘要进行最后更新
    sha.update(data.getBytes());
    // 完成摘要计算
    byte[] bytes = sha.digest();
    // 将得到的字节数组变成字符串返回
    return byteArrayToHexString(bytes);
    }
    /**
    * 将一个字节转化成十六进制形式的字符串
    * @param b 字节数组
    * @return 字符串
    */
    private static String byteToHexString(byte b) {
    int ret = b;
    //System.out.println("ret = " + ret);
    if (ret < 0) {
    ret += 256;
    }
    int m = ret / 16;
    int n = ret % 16;
    return hexDigits[m] + hexDigits[n];
    }

    /**
    * 转换字节数组为十六进制字符串
    * @param bytes 字节数组
    * @return 十六进制字符串
    */
    private static String byteArrayToHexString(byte[] bytes) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < bytes.length; i++) {
    sb.append(byteToHexString(bytes[i]));
    }
    return sb.toString();
    }
    public static void main(String[] args) throws Exception {
    String key = "123";
    System.out.println(encryptSHA(key));
    }
    }

    HMAC demo:

    public class HmacTest {
    /**
    * 定义加密方式
    * MAC算法可选以下多种算法
    * <pre>
    * HmacMD5
    * HmacSHA1
    * HmacSHA256
    * HmacSHA384
    * HmacSHA512
    * </pre>
    */
    private final static String KEY_MAC = "HmacSHA1";
    /**
    * 全局数组
    */
    private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
    "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    /**
    * 构造函数
    */
    public HmacTest() {}

    /**
    * BASE64 加密
    * @param key 需要加密的字节数组
    * @return 字符串
    * @throws Exception
    */
    public static String encryptBase64(byte[] key) throws Exception {
    return (new BASE64Encoder()).encodeBuffer(key);
    }
    /**
    * BASE64 解密
    * @param key 需要解密的字符串
    * @return 字节数组
    * @throws Exception
    */
    public static byte[] decryptBase64(String key) throws Exception {
    return (new BASE64Decoder()).decodeBuffer(key);
    }
    /**
    * 初始化HMAC密钥
    * @return
    */
    public static String init() {
    SecretKey key;
    String str = "";
    try {
    KeyGenerator generator = KeyGenerator.getInstance(KEY_MAC);
    key = generator.generateKey();
    str = encryptBase64(key.getEncoded());
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return str;
    }
    /**
    * HMAC加密
    * @param data 需要加密的字节数组
    * @param key 密钥
    * @return 字节数组
    */
    public static byte[] encryptHMAC(byte[] data, String key) {
    SecretKey secretKey;
    byte[] bytes = null;
    try {
    secretKey = new SecretKeySpec(decryptBase64(key), KEY_MAC);
    Mac mac = Mac.getInstance(secretKey.getAlgorithm());
    mac.init(secretKey);
    bytes = mac.doFinal(data);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return bytes;
    }
    /**
    * HMAC加密
    * @param data 需要加密的字符串
    * @param key 密钥
    * @return 字符串
    */
    public static String encryptHMAC(String data, String key) {
    if (Strings.isNullOrEmpty(data)) {
    return null;
    }
    byte[] bytes = encryptHMAC(data.getBytes(), key);
    return byteArrayToHexString(bytes);
    }
    /**
    * 将一个字节转化成十六进制形式的字符串
    * @param b 字节数组
    * @return 字符串
    */
    private static String byteToHexString(byte b) {
    int ret = b;
    //System.out.println("ret = " + ret);
    if (ret < 0) {
    ret += 256;
    }
    int m = ret / 16;
    int n = ret % 16;
    return hexDigits[m] + hexDigits[n];
    }

    /**
    * 转换字节数组为十六进制字符串
    * @param bytes 字节数组
    * @return 十六进制字符串
    */
    private static String byteArrayToHexString(byte[] bytes) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < bytes.length; i++) {
    sb.append(byteToHexString(bytes[i]));
    }
    return sb.toString();
    }
    public static void main(String[] args) throws Exception {
    String key = HmacTest.init();
    System.out.println("Mac密钥:" + key);
    String word = "123";
    System.out.println(encryptHMAC(word, key));
    System.out.println(encryptHMAC("0f93ddc47951f20cd972110a7d395be7754df583",key));

    }
    }

    base64在sha,hmac中基本都有用到,先用base64先转码以下,再用相应的加密方法。

    md5单项加密,适用于对用户的密码进行加密;

    sha这个加密方法我曾经在redis官方文档里有看到,不知道用没用过,在听公司前辈讲,win系统中使用的加密方法就有sha。

    二.对称加密算法(加密过程可逆)

    方法:

    DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”;

    3DES,也就是“Triple DES”,中文名“三重数据加密算法”;

    AES,全称为“Advanced Encryption Standard”,中文名“高级加密标准。

    由于三类方法用的api都是密码器cipher,只是参数不同,

    所以我直接写了一个demo,参数请看注释:

    public class DesTest {
    /**
    * 定义加密方式
    */
    // private final static String KEY = "AES";
    private final static String KEY = "DES";
    // private final static String KEY = "DESede";

    // DES算法必须是56位
    // DESede算法可以是112位或168位
    // AES算法可以是128、192、256位
    private final static Integer KEY_num = 56;
    /**
    * 全局数组
    */
    private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
    "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    /**
    * 初始化密钥
    * @return
    */
    public static SecretKey init() {
    SecretKey key =null;
    try {
    KeyGenerator generator = KeyGenerator.getInstance(KEY);// 获取密匙生成器
    // DES算法必须是56位
    // DESede算法可以是112位或168位
    // AES算法可以是128、192、256位
    generator.init(KEY_num);// 初始化

    key = generator.generateKey();// 生成密匙,可用多种方法来保存密匙
    } catch (Exception e) {
    e.printStackTrace();
    }
    return key;
    }

    /**
    * DES 解密
    * @param data 需要解密的字符串
    * @param key 密钥
    * @return
    */
    public static String decryptDES(String data, SecretKey key) {
    // 验证传入的字符串
    if (Strings.isNullOrEmpty(data)) {
    return "";
    }
    // 调用解密方法完成解密
    byte[] bytes = null;
    try {
    Cipher cipher = Cipher.getInstance(KEY);// 创建密码器
    cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
    bytes = cipher.doFinal(hexString2Bytes(data));// 解密
    } catch (Exception e) {
    e.printStackTrace();
    }
    // 将得到的字节数组变成字符串返回
    return new String(bytes);
    }


    /**
    * DES 加密
    * @param data 需要加密的字符串
    * @param key 密钥
    * @return
    */
    public static String encryptDES(String data, SecretKey key) {
    // 验证传入的字符串
    if (Strings.isNullOrEmpty(data)) {
    return "";
    }
    // 调用加密方法完成加密
    byte[] bytes=null;
    try {
    Cipher cipher = Cipher.getInstance(KEY);// 创建密码器
    cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
    bytes = cipher.doFinal(data.getBytes());
    } catch (Exception e) {
    e.printStackTrace();
    }
    // 将得到的字节数组变成字符串(十六进制)返回
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < bytes.length; i++) {
    sb.append(byteToHexString(bytes[i]));
    }
    return sb.toString();
    }


    /**
    * 将一个字节转化成十六进制形式的字符串
    * @param b 字节数组
    * @return 字符串
    */
    private static String byteToHexString(byte b) {
    int ret = b;
    //System.out.println("ret = " + ret);
    if (ret < 0) {
    ret += 256;
    }
    int m = ret / 16;
    int n = ret % 16;
    return hexDigits[m] + hexDigits[n];
    }



    /**
    * 转换十六进制字符串为字节数组
    * @param hexstr 十六进制字符串
    * @return
    */
    public static byte[] hexString2Bytes(String hexstr) {
    byte[] b = new byte[hexstr.length() / 2];
    int j = 0;
    for (int i = 0; i < b.length; i++) {
    char c0 = hexstr.charAt(j++);
    char c1 = hexstr.charAt(j++);
    b[i] = (byte) ((parse(c0) << 4) | parse(c1));
    }
    return b;
    }

    /**
    * 转换字符类型数据为整型数据
    * @param c 字符
    * @return
    */
    private static int parse(char c) {
    if (c >= 'a')
    return (c - 'a' + 10) & 0x0f;
    if (c >= 'A')
    return (c - 'A' + 10) & 0x0f;
    return (c - '0') & 0x0f;
    }

    /**
    * 测试方法
    * @param args
    */
    public static void main(String[] args) {
    SecretKey key = DesTest.init();
    System.out.println("DES密钥: " + key.getAlgorithm());

    String word = "123";


    String encWord = encryptDES(word, key);

    System.out.println(word + "加密后:" + encWord);
    System.out.println(word + "解密后:" + decryptDES(encWord, key));
    }
    }

    三:非对称加密算法

    RSA;

    DH,全称为“Diffie-Hellman”,他是一种确保共享KEY安全穿越不安全网络的方法,也就是常说的密钥一致协议。

    rsa demo:

    public class RsaTest {
    /**
    * 定义加密方式
    */
    private final static String KEY_RSA = "RSA";
    /**
    * 定义签名算法
    */
    private final static String KEY_RSA_SIGNATURE = "MD5withRSA";
    /**
    * 定义公钥算法
    */
    private final static String KEY_RSA_PUBLICKEY = "RSAPublicKey";
    /**
    * 定义私钥算法
    */
    private final static String KEY_RSA_PRIVATEKEY = "RSAPrivateKey";

    /**
    * 初始化密钥
    * @return
    */
    public static Map<String, Object> init() {
    Map<String, Object> map = null;
    try {
    KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
    generator.initialize(1024);//秘钥长度
    KeyPair keyPair = generator.generateKeyPair();//生成密钥对
    // 公钥
    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    // 私钥
    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    // 将密钥封装为map
    map = Maps.newHashMap();
    map.put(KEY_RSA_PUBLICKEY, publicKey);
    map.put(KEY_RSA_PRIVATEKEY, privateKey);
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    }
    return map;
    }

    /**
    * 用私钥对信息生成数字签名
    * @param data 加密数据
    * @param privateKey 私钥
    * @return
    */
    public static String sign(byte[] data, String privateKey) {
    String str = "";
    try {
    // 解密由base64编码的私钥
    byte[] bytes = decryptBase64(privateKey);
    // 构造PKCS8EncodedKeySpec对象
    PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
    // 指定的加密算法
    KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
    // 取私钥对象
    PrivateKey key = factory.generatePrivate(pkcs);
    // 用私钥对信息生成数字签名
    Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
    signature.initSign(key);
    signature.update(data);
    str = encryptBase64(signature.sign());
    } catch (Exception e) {
    e.printStackTrace();
    }
    return str;
    }

    /**
    * 校验数字签名
    * @param data 加密数据
    * @param publicKey 公钥
    * @param sign 数字签名
    * @return 校验成功返回true,失败返回false
    */
    public static boolean verify(byte[] data, String publicKey, String sign) {
    boolean flag = false;
    try {
    // 解密由base64编码的公钥
    byte[] bytes = decryptBase64(publicKey);
    // 构造X509EncodedKeySpec对象
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
    // 指定的加密算法
    KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
    // 取公钥对象
    PublicKey key = factory.generatePublic(keySpec);
    // 用公钥验证数字签名
    Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
    signature.initVerify(key);
    signature.update(data);
    flag = signature.verify(decryptBase64(sign));
    } catch (Exception e) {
    e.printStackTrace();
    }
    return flag;
    }

    /**
    * 私钥解密
    * @param data 加密数据
    * @param key 私钥
    * @return
    */
    public static byte[] decryptByPrivateKey(byte[] data, String key) {
    byte[] result = null;
    try {
    // 对私钥解密
    byte[] bytes = decryptBase64(key);
    // 取得私钥
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
    KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
    PrivateKey privateKey = factory.generatePrivate(keySpec);
    // 对数据解密
    Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    result = cipher.doFinal(data);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return result;
    }

    /**
    * 私钥解密
    * @param data 加密数据
    * @param key 公钥
    * @return
    */
    public static byte[] decryptByPublicKey(byte[] data, String key) {
    byte[] result = null;
    try {
    // 对公钥解密
    byte[] bytes = decryptBase64(key);
    // 取得公钥
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
    KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
    PublicKey publicKey = factory.generatePublic(keySpec);
    // 对数据解密
    Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, publicKey);
    result = cipher.doFinal(data);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return result;
    }

    /**
    * 公钥加密
    * @param data 待加密数据
    * @param key 公钥
    * @return
    */
    public static byte[] encryptByPublicKey(byte[] data, String key) {
    byte[] result = null;
    try {
    byte[] bytes = decryptBase64(key);
    // 取得公钥
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
    KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
    // generatePublic:根据提供的密钥规范(密钥材料)生成私钥对象。
    PublicKey publicKey = factory.generatePublic(keySpec);
    // 对数据加密
    Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    result = cipher.doFinal(data);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return result;
    }

    /**
    * 私钥加密
    * @param data 待加密数据
    * @param key 私钥
    * @return
    */
    public static byte[] encryptByPrivateKey(byte[] data, String key) {
    byte[] result = null;
    try {
    byte[] bytes = decryptBase64(key);
    // 取得私钥
    // 此类表示按照 ASN.1 类型 PrivateKeyInfo 进行编码的专用密钥的 ASN.1 编码。
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
    KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
    // generatePrivate:根据提供的密钥规范(密钥材料)生成私钥对象。
    PrivateKey privateKey = factory.generatePrivate(keySpec);
    // 对数据加密
    Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    result = cipher.doFinal(data);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return result;
    }

    /**
    * 获取公钥
    * @param map
    * @return
    */
    public static String getPublicKey(Map<String, Object> map) {
    String str = "";
    try {
    Key key = (Key) map.get(KEY_RSA_PUBLICKEY);
    str = encryptBase64(key.getEncoded());
    } catch (Exception e) {
    e.printStackTrace();
    }
    return str;
    }

    /**
    * 获取私钥
    * @param map
    * @return
    */
    public static String getPrivateKey(Map<String, Object> map) {
    String str = "";
    try {
    Key key = (Key) map.get(KEY_RSA_PRIVATEKEY);
    str = encryptBase64(key.getEncoded());
    } catch (Exception e) {
    e.printStackTrace();
    }
    return str;
    }

    /**
    * BASE64 解密
    * @param key 需要解密的字符串
    * @return 字节数组
    * @throws Exception
    */
    public static byte[] decryptBase64(String key) throws Exception {
    return (new BASE64Decoder()).decodeBuffer(key);
    }

    /**
    * BASE64 加密
    * @param key 需要加密的字节数组
    * @return 字符串
    * @throws Exception
    */
    public static String encryptBase64(byte[] key) throws Exception {
    return (new BASE64Encoder()).encodeBuffer(key);
    }

    /**
    * 测试方法
    * @param args
    */
    public static void main(String[] args) {
    String privateKey = "";
    String publicKey = "";
    // 生成公钥私钥
    Map<String, Object> map = init();
    publicKey = getPublicKey(map);
    privateKey = getPrivateKey(map);
    System.out.println("公钥: " + publicKey);
    System.out.println("私钥: " + privateKey);
    System.out.println("公钥加密--------私钥解密");
    String word = "你好,世界!";
    byte[] encWord = encryptByPublicKey(word.getBytes(), publicKey);
    String decWord = new String(decryptByPrivateKey(encWord, privateKey));
    System.out.println("加密前: " + word + " " + "解密后: " + decWord);
    System.out.println("私钥加密--------公钥解密");
    String english = "Hello, World!";
    byte[] encEnglish = encryptByPrivateKey(english.getBytes(), privateKey);
    String decEnglish = new String(decryptByPublicKey(encEnglish, publicKey));
    System.out.println("加密前: " + english + " " + "解密后: " + decEnglish);
    System.out.println("私钥签名——公钥验证签名");
    // 产生签名
    String sign = sign(encEnglish, privateKey);
    System.out.println("签名: " + sign);
    // 验证签名
    boolean status = verify(encEnglish, publicKey, sign);
    System.out.println("状态: " + status);
    }
    }
    //生成密匙    KeyPairGenerator
    //创建密码器 Cipher
    //Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
    //Only RSAPrivate(Crt)KeySpec and PKCS8EncodedKeySpec supported for RSA private keys

    dh  demo:

    public class DhTest {
    /**
    * 定义加密方式
    */
    private static final String KEY_DH = "DH";
    /**
    * 默认密钥字节数
    */
    private static final int KEY_SIZE = 1024;
    /**
    * DH加密下需要一种对称加密算法对数据加密,这里我们使用DES,也可以使用其他对称加密算法
    */
    private static final String KEY_DH_DES = "DES";
    private static final String KEY_DH_PUBLICKEY = "DHPublicKey";
    private static final String KEY_DH_PRIVATEKEY = "DHPrivateKey";

    /**
    * 初始化甲方密钥
    * @return
    */
    public static Map<String, Object> init() {
    Map<String, Object> map = null;
    try {
    KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_DH);
    generator.initialize(KEY_SIZE);
    KeyPair keyPair = generator.generateKeyPair();
    // 甲方公钥
    DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();
    // 甲方私钥
    DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();
    map = Maps.newHashMap();
    map.put(KEY_DH_PUBLICKEY, publicKey);
    map.put(KEY_DH_PRIVATEKEY, privateKey);
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    }
    return map;
    }

    /**
    * 初始化乙方密钥
    * @param key 甲方密钥
    * @return
    */
    public static Map<String, Object> init(String key) {
    Map<String, Object> map = null;
    try {
    // 解析甲方密钥
    byte[] bytes = decryptBase64(key);
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
    KeyFactory factory = KeyFactory.getInstance(KEY_DH);
    PublicKey publicKey = factory.generatePublic(keySpec);

    // 由甲方公钥构建乙方密钥
    DHParameterSpec spec = ((DHPublicKey) publicKey).getParams();
    KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_DH);
    generator.initialize(spec);
    KeyPair keyPair = generator.generateKeyPair();
    // 乙方公钥
    DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
    // 乙方私钥
    DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
    map = Maps.newHashMap();
    map.put(KEY_DH_PUBLICKEY, dhPublicKey);
    map.put(KEY_DH_PRIVATEKEY, dhPrivateKey);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return map;
    }

    /**
    * DH 加密
    * @param data 带加密数据
    * @param publicKey 甲方公钥
    * @param privateKey 乙方私钥
    * @return
    */
    public static byte[] encryptDH(byte[] data, String publicKey, String privateKey) {
    byte[] bytes = null;
    try {
    // 生成本地密钥
    SecretKey secretKey = getSecretKey(publicKey, privateKey);
    System.out.println("secretKey`````````````````"+secretKey);
    // 数据加密
    Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    bytes = cipher.doFinal(data);
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    } catch (NoSuchPaddingException e) {
    e.printStackTrace();
    } catch (InvalidKeyException e) {
    e.printStackTrace();
    } catch (BadPaddingException e) {
    e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
    e.printStackTrace();
    }
    return bytes;
    }

    /**
    * DH 解密
    * @param data 待解密数据
    * @param publicKey 乙方公钥
    * @param privateKey 甲方私钥
    * @return
    */
    public static byte[] decryptDH(byte[] data, String publicKey, String privateKey) {
    byte[] bytes = null;
    try {
    // 生成本地密钥
    SecretKey secretKey = getSecretKey(publicKey, privateKey);
    System.out.println("secretKey`````````````````"+secretKey);
    // 数据解密
    Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    bytes = cipher.doFinal(data);
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    } catch (NoSuchPaddingException e) {
    e.printStackTrace();
    } catch (InvalidKeyException e) {
    e.printStackTrace();
    } catch (BadPaddingException e) {
    e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
    e.printStackTrace();
    }
    return bytes;
    }

    /**
    * 取得私钥
    * @param map
    * @return
    */
    public static String getPrivateKey(Map<String, Object> map) {
    String str = "";
    try {
    Key key = (Key) map.get(KEY_DH_PRIVATEKEY);
    str = encryptBase64(key.getEncoded());
    } catch (Exception e) {
    e.printStackTrace();
    }
    return str;
    }

    /**
    * 取得公钥
    * @param map
    * @return
    */
    public static String getPublicKey(Map<String, Object> map) {
    String str = "";
    try {
    Key key = (Key) map.get(KEY_DH_PUBLICKEY);
    str = encryptBase64(key.getEncoded());
    } catch (Exception e) {
    e.printStackTrace();
    }
    return str;
    }

    /**
    * 构建本地密钥
    * @param publicKey 公钥
    * @param privateKey 私钥
    * @return
    */
    private static SecretKey getSecretKey(String publicKey, String privateKey) {
    SecretKey secretKey = null;
    try {
    // 初始化公钥
    byte[] publicBytes = decryptBase64(publicKey);
    KeyFactory factory = KeyFactory.getInstance(KEY_DH);
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
    PublicKey localPublicKey = factory.generatePublic(keySpec);

    // 初始化私钥
    byte[] privateBytes = decryptBase64(privateKey);
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateBytes);
    PrivateKey localPrivateKey = factory.generatePrivate(spec);

    KeyAgreement agreement = KeyAgreement.getInstance(factory.getAlgorithm());
    agreement.init(localPrivateKey);
    agreement.doPhase(localPublicKey, true);

    // 生成本地密钥
    secretKey = agreement.generateSecret(KEY_DH_DES);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return secretKey;
    }

    /**
    * BASE64 解密
    * @param key 需要解密的字符串
    * @return 字节数组
    * @throws Exception
    */
    public static byte[] decryptBase64(String key) throws Exception {
    return (new BASE64Decoder()).decodeBuffer(key);
    }

    /**
    * BASE64 加密
    * @param key 需要加密的字节数组
    * @return 字符串
    * @throws Exception
    */
    public static String encryptBase64(byte[] key) throws Exception {
    return (new BASE64Encoder()).encodeBuffer(key);
    }

    /**
    * 测试方法
    * @param args
    */
    public static void main(String[] args) {
    // 生成甲方密钥对
    Map<String, Object> mapA = init();
    String publicKeyA = getPublicKey(mapA);
    String privateKeyA = getPrivateKey(mapA);
    System.out.println("甲方公钥: " + publicKeyA);
    System.out.println("甲方私钥: " + privateKeyA);

    // 由甲方公钥产生本地密钥对
    Map<String, Object> mapB = init(publicKeyA);
    String publicKeyB = getPublicKey(mapB);
    String privateKeyB = getPrivateKey(mapB);
    System.out.println("乙方公钥: " + publicKeyB);
    System.out.println("乙方私钥: " + privateKeyB);

    String word = "abc";
    System.out.println("原文: " + word);

    // 由甲方公钥,乙方私钥构建密文
    byte[] encWord = encryptDH(word.getBytes(), publicKeyA, privateKeyB);

    // 由乙方公钥,甲方私钥解密
    byte[] decWord = decryptDH(encWord, publicKeyB, privateKeyA);
    System.out.println("解密: " + new String(decWord));

    }
    }

                        单向加密:  不要求识别原始字符串,只要保证字符串与原始字符串相同。   用户注册账号,保存密码,先加密,在保存到数据库,登陆时,将用户输入的密码单向加密获取加密后的字符串A,去数据库查找字符串A。

                        对称加密:  甲乙双方使用相同的秘钥(一个)。

    要求在 甲方发送到乙方   的传输过程中的是 原文加密后的字符串;且在乙方可以解密成原文。

                        非对称加密: 甲乙上双方各产生一对秘钥,公钥公开,用于加密原文,私钥用于解密接收到的字符串,还原成原文。rsa

    甲方产生一对秘钥,公开公钥,乙方根据甲方提供的公钥产生自己的一对秘钥。dh:

    构件密文:甲方的公钥+乙方的私钥-----》加密秘钥;(乙方发送给甲方)

    解密: 甲方的秘钥+乙方的公钥-------》解密秘钥;(甲方接受原文)。

    (demo手敲,敲代码是方式,目的是更懂代码。)

    以上。

    参考博客:http://blog.csdn.net/happylee6688/article/category/2902645

    • HMAC(Hash Message Authentication Code,散列消息鉴别码

    •  

    SHA-1 与 MD5 的比较

    因为二者均由 MD4 导出,SHA-1 和 MD5 彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:

    • 对强行攻击的安全性

    最显著和最重要的区别是 SHA-1 摘要比 MD5 摘要长 32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对 MD5 是 2^128 数量级的操作,而对 SHA-1 则是 2^160 数量级的操作。这样,SHA-1 对强行攻击有更大的强度。

    • 对密码分析的安全性

    由于 MD5 的设计,易受密码分析的攻击,SHA-1 显得不易受这样的攻击。

    • 速度

    在相同的硬件上,SHA-1 的运行速度比 MD5 慢。

    public class Md5Test {
        public  static String MD5(String s) {
    
            if(s==null && s.equals("")){
                return null;
            }
            char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
            try {
                byte[] btInput = s.getBytes();
                // 获得MD5摘要算法的 MessageDigest 对象
                MessageDigest mdInst = MessageDigest.getInstance("MD5");
                // 使用指定的字节更新摘要
                mdInst.update(btInput);
                // 获得密文
                byte[] md = mdInst.digest();
                // 把密文转换成十六进制的字符串形式
                int j = md.length;
                char str[] = new char[j * 2];
                int k = 0;
                for (int i = 0; i < j; i++) {
                    byte byte0 = md[i];
    //                定义转换成16进制的算法
                    str[k++] = hexDigits[byte0 >>> 5 & 0xf];
                    str[k++] = hexDigits[byte0 & 0xf];
                }
                return new String(str);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        public static void main(String[] args) {
            System.out.println(MD5("admin"));
            System.out.println(MD5("加密"));
        }
    }
    public class Base64Test {
    
    //    解密
        public static String  getFromBase64(String s){
            byte[] b = null;
            String result = null;
            if (s != null) {
                BASE64Decoder decoder=new BASE64Decoder();
                try {
                    b=decoder.decodeBuffer(s);
                    result=new String(b,"utf-8");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return result;
        }
    //    加密
        public static String getBase64(String s){
            byte[] b = null;
            String result = null;
            try {
                b=s.getBytes("utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (b != null) {
                result = new BASE64Encoder().encode(b);
            }
            return result;
        }
    
        public static void main(String [] args){
            System.out.println(getBase64("admin"));
            System.out.println(getFromBase64("YWRtaW4="));
        }
    }
    public class ShaTest {
        /**
         * 定义加密方式
         */
        private final static String KEY_SHA = "SHA";
        private final static String KEY_SHA1 = "SHA-1";
        private final static String KEY_SHA224 = "SHA-224";
        private final static String KEY_SHA256 = "SHA-256";
        /**
         * 全局数组
         */
        private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
                "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    
        /**
         * 构造函数
         */
        public ShaTest() {}
    
        /**
         * SHA 加密
         * @param data 需要加密的字符串
         * @return 加密之后的字符串
         * @throws Exception
         */
        public static String encryptSHA(String data) throws Exception {
            // 验证传入的字符串
            if (Strings.isNullOrEmpty(data)) {
                return "";
            }
            // 创建具有指定算法名称的信息摘要
            MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
            // 使用指定的字节数组对摘要进行最后更新
            sha.update(data.getBytes());
            // 完成摘要计算
            byte[] bytes = sha.digest();
            // 将得到的字节数组变成字符串返回
            return byteArrayToHexString(bytes);
        }
        /**
         * 将一个字节转化成十六进制形式的字符串
         * @param b 字节数组
         * @return 字符串
         */
        private static String byteToHexString(byte b) {
            int ret = b;
            //System.out.println("ret = " + ret);
            if (ret < 0) {
                ret += 256;
            }
            int m = ret / 16;
            int n = ret % 16;
            return hexDigits[m] + hexDigits[n];
        }
    
        /**
         * 转换字节数组为十六进制字符串
         * @param bytes 字节数组
         * @return 十六进制字符串
         */
        private static String byteArrayToHexString(byte[] bytes) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < bytes.length; i++) {
                sb.append(byteToHexString(bytes[i]));
            }
            return sb.toString();
        }
        public static void main(String[] args) throws Exception {
            String key = "123";
            System.out.println(encryptSHA(key));
        }
    }

    base64

    MD5

    SHA

    对称加密算法

    模型:

     
     
     
     
     

     加密过程可逆

     
     
     

    工具:秘钥(一个)

    加密

    解密

     
     

    DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”;

    3DES,也就是“Triple DES”,中文名“三重数据加密算法”;

    AES,全称为“Advanced Encryption Standard”,中文名“高级加密标准

    非对称加密算法

    模型:

     
     
     
     
     

    加密过程可逆 

     
     
     

    工具:秘钥(两个)

    加密

    解密

     
     
     
  • 相关阅读:
    第二章 金字塔内部的结构
    第一章 为什么要用金字塔结构
    考研级《计算机网络》知识梳理——第二期
    考研级《计算机网络》知识梳理——第一期
    leetcode常规算法题复盘(科普短文篇)——为何哈希表的容量一般是质数
    leetcode常规算法题复盘(第十六期)——数据流中的第 K 大元素
    leetcode常规算法题复盘(第十四期)——最后一块石头的重量
    leetcode常规算法题复盘(第十三期)——最大矩形&柱状图中最大的矩形
    leetcode常规算法题复盘(第十二期)——摆动序列&买卖股票的最佳时机含手续费
    leetcode常规算法题复盘(基础篇)——线性表java实现
  • 原文地址:https://www.cnblogs.com/zqsky/p/6085551.html
Copyright © 2011-2022 走看看