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”,中文名“高级加密标准

    非对称加密算法

    模型:

     
     
     
     
     

    加密过程可逆 

     
     
     

    工具:秘钥(两个)

    加密

    解密

     
     
     
  • 相关阅读:
    微信小程序 单选按钮 最佳
    微信小程序 单选按钮的实现
    微信小程序 单选框实现
    Java Code To Create Pyramid and Pattern
    Java language
    npm Err! Unexpected end of JSON input while parsing near
    Node.js Express FrameWork Tutorial
    Higher-Order Function Examples
    Create First HTTP Web Server in Node.js: Complete Tutorial
    Node.js NPM Tutorial: Create, Publish, Extend & Manage
  • 原文地址:https://www.cnblogs.com/zqsky/p/6085551.html
Copyright © 2011-2022 走看看