常用加密算法梳理

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

一、对称加密

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

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

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

1.1、对称加密之AES

1.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.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.1.3、测试结果
1.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();
}

1.2、对称加密之DES

1.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;
}
1.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);
}
1.2.3、测试结果

1.3、对称加密之SHA

1.3.1、SHA加密

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;
}
1.3.2、测试结果

二、非对称加密

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

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

2.1、对称加密算法之MD5

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;

}
2.1.2、测试结果

2.2、对称加密算法之RSA

2.2.1、RSA加解密算法

这里只是简单地利用了公钥加密,私钥解密,较为全面的还有私钥加密,公钥解密,更为全面的请参考Central-Perk的博客

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);
}
2.2.2、测试结果

参考博客:

http://blog.csdn.net/centralperk/article/details/8538697

http://blog.csdn.net/houzuoxin/article/details/39054895

三、视频快速加密

对于大文件加解密使用传统方式比较费时间,这种场景可使用

本地视频快速加密与解密工具类,附视频地址

public class JavaTest {
    private final int REVERSE_LENGTH = 10;
    /**
     * 加解密
     *
     * @param strFile 源文件绝对路径
     * @return
     */
    private boolean encrypt(String strFile) {
        int len = REVERSE_LENGTH;
        try {
            File f = new File(strFile);
            RandomAccessFile raf = new RandomAccessFile(f, "rw");
            long totalLen = raf.length();

            if (totalLen < REVERSE_LENGTH)
                len = (int) totalLen;

            FileChannel channel = raf.getChannel();
            MappedByteBuffer buffer = channel.map(
                    FileChannel.MapMode.READ_WRITE, 0, REVERSE_LENGTH);
            byte tmp;
            for (int i = 0; i < len; ++i) {
                byte rawByte = buffer.get(i);
                tmp = (byte) (rawByte ^ i);
                buffer.put(i, tmp);
            }
            buffer.force();
            buffer.clear();
            channel.close();
            raf.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static void main(String[] args) {
        new JavaTest().encrypt("/Users/zhanglei/Desktop/惊鸿一面.mp4");
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
前端常用加密算法包括: 1. 对称加密算法:如AES(Advanced Encryption Standard)、DES(Data Encryption Standard)和3DES(Triple Data Encryption Standard),特点是加密解密速度快,但密钥安全性较低。 2. 非对称加密算法:如RSA(Rivest-Shamir-Adleman)和ECC(Elliptic Curve Cryptography),特点是加密解密速度较慢,但密钥安全性较高。 3. 哈希算法:如MD5(Message-Digest Algorithm 5)和SHA(Secure Hash Algorithm),特点是不可逆且不同的明文生成的哈希值相同的概率极小。 4. 对称加密算法与非对称加密算法结合使用:如SSL(Secure Socket Layer)和TLS(Transport Layer Security),通过使用对称加密算法加密通信过程中的数据,使用非对称加密算法加密密钥,从而兼顾了加密速度和密钥安全性。 常用加密算法的特点主要包括: 1. 加密强度:指加密算法对攻击者破解的难度,一般用密钥长度来衡量,密钥长度越长,加密强度越高。 2. 加密速度:指加密算法对数据加密、解密的速度,一般对称加密算法速度较快,非对称加密算法速度较慢。 3. 密钥管理:指加密算法对密钥生成、存储、分发和更新的支持程度,一般非对称加密算法需要密钥管理较为复杂。 4. 可逆性:指加密算法是否支持加密后数据可逆解密,对称加密算法和非对称加密算法的可逆性不同。 5. 安全性:指加密算法的安全性是否被攻击者破解,一般安全性高的加密算法需要较高的加密强度和密钥管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流星雨在线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值