对称加密与非对称加密笔记_one

来源:互联网 发布:淘宝美胸第一名 编辑:程序博客网 时间:2024/05/05 19:59

前言:

因为加密算法用的比较多,这里就常用的加密算法(如AES、DES、MD5、SHA1、SHA256、SHA512、RSA等加密算法)基于基本用法结合实际应用做一个总结笔记。因为加密算法的具体方法与类都在jdk中有封装好,关于里面的详细逻辑会在后面的章节里写出来,这里仅以应用为主。

一、对称加密:双方使用的同一个密钥,既可以加密又可以解密,这种加密方法称为对称加密,也称为单密钥加密。

优点:速度快,对称性加密通常在消息发送方需要加密大量数据时使用,算法公开、计算量小、加密速度快、加密效率高。

缺点:在数据传送前,发送方和接收方必须商定好秘钥,然后 使双方都能保存好秘钥。其次如果一方的秘钥被泄露,那么加密信息也就不安全了。另外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的唯一秘钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理成为双方的负担。

1.1,  对称加密之AES加密

//AES加密public static byte[] encrypt(String content, String password) {          try {                             KeyGenerator kgen = KeyGenerator.getInstance("AES");  //(对称)密钥生成器                kgen.init(128, new SecureRandom(password.getBytes()));  //显式地初始化 KeyGenerator(通过调用 init 方法)                SecretKey secretKey = kgen.generateKey();                  byte[] enCodeFormat = secretKey.getEncoded();                  SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");                  Cipher cipher = Cipher.getInstance("AES");// 创建密码器                  byte[] byteContent = content.getBytes("utf-8");                  cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化                  byte[] result = cipher.doFinal(byteContent);                  return result; // 加密          } catch (Exception e) {          }         return null;  }  
1.2,  对称加密之AES解密

//AES解密public static byte[] decrypt(byte[] content, String password) {          try {                   KeyGenerator kgen = KeyGenerator.getInstance("AES");                   kgen.init(128, new SecureRandom(password.getBytes()));                   SecretKey secretKey = kgen.generateKey();                   byte[] enCodeFormat = secretKey.getEncoded();                   SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");                               Cipher cipher = Cipher.getInstance("AES");// 创建密码器                  cipher.init(Cipher.DECRYPT_MODE, key);// 初始化                  byte[] result = cipher.doFinal(content);                  return result; // 加密          } catch (Exception e) {                e.printStackTrace();          }         return null;  }  
1.3,测试结果
测试结果








































1.4,应用
该AES适合加密字符串,当然也可以加密文件如音视频媒体文件、可执行文件等,但这种加密对于大的文件比较耗时,下面贴出自己平常使用中的AES加密算法,这个是另外一种AES加密,但这种对于加密字符串有缺点,
  • 密钥必须是16位的
  • 待加密内容的长度必须是16的倍数,如果不是16的倍数,就会出异常
这里是代码:

//手机常用路径记录/sdcard/DCIM/Camera/VID_20140217_144346.mp4// 原文件private static final String filePath = "F:/惊鸿一面mv.mp4";// 加密后的文件private static final String outPath = "F:/惊鸿一面mvAES加密.mp4";// 加密再解密后的文件private static final String inPath = "F:/惊鸿一面mvAES解密.mp4";
//AES加密文件算法private void encrypt() throws Exception{FileInputStream fis = new FileInputStream(filePath);FileOutputStream fos = new FileOutputStream(outPath);SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),// Length is 16 byte"AES");Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE, sks);CipherOutputStream cos = new CipherOutputStream(fos, cipher);int b;byte[] d = new byte[8];while ((b = fis.read(d)) != -1) {cos.write(d, 0, b);}// Flush and close streams.cos.flush();cos.close();fis.close();}
//AES解密文件算法private void decrypt() throws Exception,{FileInputStream fis = new FileInputStream(outPath);FileOutputStream fos = new FileOutputStream(inPath);SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),"AES");Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.DECRYPT_MODE, sks);CipherInputStream cis = new CipherInputStream(fis, cipher);int b;byte[] d = new byte[8];while ((b = cis.read(d)) != -1) {fos.write(d, 0, b);}fos.flush();fos.close();cis.close();}
2.1,对称加密之DES加密
des对称加密算法现不推荐使用,因为des使用56位密钥,以现代计算能力,24小时内即可被破解,另外密码key须是8的整数倍,下面还是将算法列举出来

//des加密算法public static byte[] encrypt2(byte[] datasource, String password) {                      try{          SecureRandom random = new SecureRandom();          DESKeySpec desKey = new DESKeySpec(password.getBytes());          //创建一个密匙工厂,然后用它把DESKeySpec转换成          SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");          SecretKey securekey = keyFactory.generateSecret(desKey);          //Cipher对象实际完成加密操作          Cipher cipher = Cipher.getInstance("DES");          //用密匙初始化Cipher对象          cipher.init(Cipher.ENCRYPT_MODE, securekey, random);          //现在,获取数据并加密          //正式执行加密操作          return cipher.doFinal(datasource);          }catch(Throwable e){                  e.printStackTrace();          }          return null;  }  
2.2,对称加密之DES解密
//des解密算法private static byte[] decrypt2(byte[] src, String password) throws Exception {          // DES算法要求有一个可信任的随机数源          SecureRandom random = new SecureRandom();          // 创建一个DESKeySpec对象          DESKeySpec desKey = new DESKeySpec(password.getBytes());          // 创建一个密匙工厂          SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");          // 将DESKeySpec对象转换成SecretKey对象          SecretKey securekey = keyFactory.generateSecret(desKey);          // Cipher对象实际完成解密操作          Cipher cipher = Cipher.getInstance("DES");          // 用密匙初始化Cipher对象          cipher.init(Cipher.DECRYPT_MODE, securekey, random);          // 真正开始解密操作          return cipher.doFinal(src);  }  
2.3,测试结果
测试结果

























3.1,对称加密之SHA加密
/**     * SHA加密     *     * @param strSrc     *            明文     * @return 加密之后的密文     */    public static String shaEncrypt(String strSrc) {        MessageDigest md = null;        String strDes = null;        byte[] bt = strSrc.getBytes();        try {            md = MessageDigest.getInstance("SHA-1");// 将此换成SHA-1、SHA-512、SHA-384等参数            md.update(bt);            strDes = bytes2Hex(md.digest()); // to HexString        } catch (NoSuchAlgorithmException e) {            return null;        }        return strDes;    }    /**     * byte数组转换为16进制字符串     *     * @param bts     *            数据源     * @return 16进制字符串     */    public static String bytes2Hex(byte[] bts) {        String des = "";        String tmp = null;        for (int i = 0; i < bts.length; i++) {            tmp = (Integer.toHexString(bts[i] & 0xFF));            if (tmp.length() == 1) {                des += "0";            }            des += tmp;        }        return des;    }
SHA系列的算法属于不可逆的单向哈希算法,主要应用还是验证如数字签名等。
3.2,测试结果
测试结果





























二、非对称加密:一对密钥由公钥和私钥组成(可以使用很多对密钥)。私钥解密公钥加密数据,公钥解密私钥加密数据(私钥公钥可以互相加密解密)。

私钥只能由一方保管,不能外泄。公钥可以交给任何请求方。


1.1,对称加密算法之MD5加解密
MD5属于hash算法,严格意义上并不算加密算法,但是这里还是列举一下其用法:
     /***      * MD5加码 生成32位md5码      */      public static String string2MD5(String inStr){          MessageDigest md5 = null;          try{              md5 = MessageDigest.getInstance("MD5");          }catch (Exception e){              System.out.println(e.toString());              e.printStackTrace();              return "";          }          char[] charArray = inStr.toCharArray();          byte[] byteArray = new byte[charArray.length];            for (int i = 0; i < charArray.length; i++)              byteArray[i] = (byte) charArray[i];          byte[] md5Bytes = md5.digest(byteArray);          StringBuffer hexValue = new StringBuffer();          for (int i = 0; i < md5Bytes.length; i++){              int val = ((int) md5Bytes[i]) & 0xff;              if (val < 16)                  hexValue.append("0");              hexValue.append(Integer.toHexString(val));          }          return hexValue.toString();        }        /**      * 加密解密算法 执行一次加密,两次解密      */       public static String convertMD5(String inStr){            char[] a = inStr.toCharArray();          for (int i = 0; i < a.length; i++){              a[i] = (char) (a[i] ^ 't');          }          String s = new String(a);          return s;        }  
1.2,测试结果
测试结果


































2.1,RSA加解密算法
     public static void generateKey() {          try {              KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");              kpg.initialize(1024);              KeyPair kp = kpg.genKeyPair();              PublicKey pbkey = kp.getPublic();              PrivateKey prkey = kp.getPrivate();              // 保存公钥              FileOutputStream f1 = new FileOutputStream("pubkey.dat");              ObjectOutputStream b1 = new ObjectOutputStream(f1);              b1.writeObject(pbkey);              // 保存私钥              FileOutputStream f2 = new FileOutputStream("privatekey.dat");              ObjectOutputStream b2 = new ObjectOutputStream(f2);              b2.writeObject(prkey);          } catch (Exception e) {          }      }      public static void encrypt() throws Exception {          String s = "helloworld";          // 获取公钥及参数e,n          FileInputStream f = new FileInputStream("pubkey.dat");          ObjectInputStream b = new ObjectInputStream(f);          RSAPublicKey pbk = (RSAPublicKey) b.readObject();          BigInteger e = pbk.getPublicExponent();          BigInteger n = pbk.getModulus();          System.out.println("e= " + e);          System.out.println("n= " + n);          // 获取明文m          byte ptext[] = s.getBytes("UTF-8");          BigInteger m = new BigInteger(ptext);          // 计算密文c          BigInteger c = m.modPow(e, n);          System.out.println("c= " + c);          // 保存密文          String cs = c.toString();          BufferedWriter out =              new BufferedWriter(                  new OutputStreamWriter(new FileOutputStream("encrypt.dat")));          out.write(cs, 0, cs.length());          out.close();      }      public static void decrypt() throws Exception {          // 读取密文          BufferedReader in =              new BufferedReader(                  new InputStreamReader(new FileInputStream("encrypt.dat")));          String ctext = in.readLine();          BigInteger c = new BigInteger(ctext);          // 读取私钥          FileInputStream f = new FileInputStream("privatekey.dat");          ObjectInputStream b = new ObjectInputStream(f);          RSAPrivateKey prk = (RSAPrivateKey) b.readObject();          BigInteger d = prk.getPrivateExponent();          // 获取私钥参数及解密          BigInteger n = prk.getModulus();          System.out.println("d= " + d);          System.out.println("n= " + n);          BigInteger m = c.modPow(d, n);          // 显示解密结果          System.out.println("m= " + m);          byte[] mt = m.toByteArray();          String s = new String(mt,"UTF-8");        System.out.println("\n解密后的明文:" + s);    }  
这里只是简单地利用了公钥加密,私钥解密,较为全面的还有私钥加密,公钥解密,更为全面的请参考Central-Perk的博客
2.2,测试结果
测试结果




























参考博客:http://blog.csdn.net/centralperk/article/details/8538697
    http://blog.csdn.net/houzuoxin/article/details/39054895
    
原创粉丝点击