引入:

现在我们来研究密码学的加密解密过程,这个十分重要,因为它是明文到密文的桥梁,从类型上分,我们又分为加密解密字符串和加密解密文件,我们这文章就讲解这些细节,主要的核心类是Cipher类。

实践:

加密字符串的一般过程为:

(1)获取一个加密用的密钥

(2)实例化Cipher对象

(3)初始化Cipher对象,指定其现在处于加密模式(ENCRYPT_MODE),并指定加密使用的密钥

(4)调用doFinal方法,传入被加密的字符串对应的字节数组,返回加密后的字节数组

解密字符串的一般过程为:

(1)获取一个解密用的密钥

(2)实例化Cipher对象

(3)初始化Cipher对象,指定其现在处于解密模式(DECRYPT_MODE),并指定解密用的密钥

(4)调用doFinal方法,传入密文字节数组,返回解密后的字节数组

加密文件的一般过程为:

(1)获取一个加密用的密钥

(2)实例化Cipher对象

(3)初始化Cipher对象,指定其现在处于加密模式(ENCRYPT_MODE),并指定加密使用的密钥

(4)打开文件输入流,指向要被加密的文件

(5)打开文件输出流,指向加密后存放的文件

(6)打开加密输入流,包装指向被加密文件的输入流

(7)读取,并且加密,加密结果写入目标文件

解密文件的一般过程为:

(1)获取一个解密用的密钥

(2)实例化Cipher对象

(3)初始化Cipher对象,指定其现在处于解密模式(DECRYPT_MODE),并指定解密用的密钥

(4)打开文件输入流,指向要被解密的文件

(5)打开文件输出流,指向解密后存放的文件

(6)打开解密输出流,包装指向解密后文件的输出流

(7)读取,并且解密,解密结果写入目标文件

为了演示上面过程,我们写了一个工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package com.charles.encryptstudy;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
/**
 *
 * Description: 这个类提供了加密解密的一般方法
 *
 * @author charles.wang
 * @created Oct 29, 2013 9:17:48 AM
 *
 */
public class EncryptUtil {
                                                                                                                                                                
    //加密解密字符串的操作方法
    /**
     * 用指定的密钥加密,吧字符串加密成字节数组
     *
     * @param data  被加密的字符串
     * @param key   加密使用的密钥
     * @return      加密后的字节流
     * @throws  InvalidKeyException
     * @throws  NoSuchPaddingException
     * @throws  NoSuchAlgorithmException
     * @throws  BadPaddingException
     * @throws  IllegalBlockSizeException
     *
     */
    public static byte[] encryptString(String data, Key key)
        throws InvalidKeyException,NoSuchPaddingException,NoSuchAlgorithmException,BadPaddingException,IllegalBlockSizeException {
        // 实例化Cipher对象用于加密操作
        Cipher cipher = Cipher.getInstance(key.getAlgorithm());
        // 初始化Cipher对象,表明这个Cipher现在处于加密模式,并且指定加密使用的密钥
        cipher.init(Cipher.ENCRYPT_MODE, key);
        // 加密过程,返回加密后的内容
        return cipher.doFinal(data.getBytes());
    }
    /**
     * 用指定的密钥解密,还原字符串
     *
     * @param data  要被解密的字节流
     * @param key   解密使用的密钥
     * @return      解密后还原的字符串
     * @throws  InvalidKeyException
     * @throws  NoSuchPaddingException
     * @throws  NoSuchAlgorithmException
     * @throws  BadPaddingException
     * @throws  IllegalBlockSizeException
     */
    public static String decryptString(byte[] data, Key key) throws InvalidKeyException,NoSuchPaddingException,NoSuchAlgorithmException,BadPaddingException,IllegalBlockSizeException {
        // 实例化Cipher对象用于解密操作
        Cipher cipher = Cipher.getInstance(key.getAlgorithm());
        // 初始化Cipher对象,表明这个Cipher现在处于解密模式,并且指定解密使用的密钥
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(data));
    }
                                                                                                                                                                
                                                                                                                                                                
                                                                                                                                                                
    //加密解密文件的操作方法
                                                                                                                                                                
    /**
     * 用指定的密钥加密文件(sourceFile),结果保存在destFile中
     *
     * @param sourceFile 要加密的文件
     * @param destFile   加密后的文件
     * @param key        加密使用的密钥
     * @throws Exception
     */
    public static void encryptFile(String sourceFile,String destFile,Key key) throws Exception{
        //实例化Cipher对象用于加密操作
        Cipher cipher = Cipher.getInstance(key.getAlgorithm());
        //初始化Cipher对象,表明这个Cipher现在处于加密模式,并且指定加密使用的密钥
        cipher.init(Cipher.ENCRYPT_MODE, key);
        //打开文件输入流,指向要被加密的文件
        InputStream is = new FileInputStream(sourceFile);
        //打开文件输出流,指向加密后存放的文件
        OutputStream os = new FileOutputStream(destFile);
                                                                                                                                                                    
        //打开加密输入流,包装指向被加密文件的输入流
        CipherInputStream cis = new CipherInputStream(is,cipher);
                                                                                                                                                                    
        //缓冲区
        byte[] buffer = new byte[1024];
        int result;
                                                                                                                                                                    
        //读取,并且加密,加密结果写入目标文件
        while ((result = cis.read(buffer)) > 0) {
            os.write(buffer, 0, result);
        }
        cis.close();
        is.close();
        os.close();
                                                                                                                                                                  
                                                                                                                                                                    
    }
                                                                                                                                                                
                                                                                                                                                                
    /**
     * 用指定的密钥解密文件(encryptedFile),结果保存在originalFile中
     *
     * @param encryptedFile 要解密的文件
     * @param originalFile   解密后的文件
     * @param key        解密使用的密钥
     * @throws Exception
     */
    public static void decryptFile(String encryptedFile,String originalFile,Key key) throws Exception{
        //实例化Cipher对象用于解密操作
        Cipher cipher = Cipher.getInstance(key.getAlgorithm());
        //初始化Cipher对象,表明这个Cipher现在处于解密模式,并且指定解密使用的密钥
        cipher.init(Cipher.DECRYPT_MODE, key);
        //打开文件输入流,指向要被解密的文件
        InputStream is = new FileInputStream(encryptedFile);
        //打开文件输出流,指向解密后存放的文件
        OutputStream os = new FileOutputStream(originalFile);
                                                                                                                                                                    
        //打开解密输出流,包装指向解密后文件的输出流
        CipherOutputStream cos = new CipherOutputStream(os,cipher);
                                                                                                                                                                    
        //缓冲区
        byte[] buffer = new byte[1024];
        int result;
                                                                                                                                                                    
        //读取,并且解密,解密结果写入目标文件
        while ((result = is.read(buffer)) > 0) {
            cos.write(buffer, 0, result);
        }
        cos.close();
        is.close();
        os.close();
                                                                                                                                                                  
                                                                                                                                                                    
    }
}

对于加密解密字符串,我们写了一个演示Demo类,来演示这2个操作结果,我们指定任意字符串,先用我们的加密方法对其加密,然后用我们的解密方法解密还原原始字符串.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.charles.encryptstudy;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
import com.charles.keystudy.SymmetricKeyUtil;
/**
 *
 * Description: 这个类用来演示如何加密和解密字符串
 *
 * @author charles.wang
 * @created Oct 28, 2013 4:37:41 PM
 *
 */
public class EncryptStringDemo {
    public static void main(String[] args) throws Exception {
                                                                                                                                         
        //我们演示加密解密字符串
        System.out.println("加密解密字符串:");
                                                                                                                                         
        String stringNeedEncrypt="加密这段文本";
        System.out.println("被加密的文本为:"+stringNeedEncrypt);
                                                                                                                                         
        //产生一个密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("DES");
        Key key=keyGen.generateKey();
        System.out.println("\n加密使用的密钥为:"+(new BASE64Encoder()).encode(key.getEncoded()));
        System.out.println("加密使用的算法为:"+key.getAlgorithm());
                                                                                                                                         
        //加密字符串过程
        System.out.println("\n开始加密字符串...");
        byte[] encryptedValue = EncryptUtil.encryptString(stringNeedEncrypt, key);
        System.out.println("加密后的密文为:"+(new BASE64Encoder()).encode(encryptedValue));
                                                                                                                                         
        //解密字符串过程
        System.out.println("\n开始解密字符串...");
        String decryptedString = EncryptUtil.decryptString(encryptedValue, key);
        System.out.println("解密后还原的字符串为:"+decryptedString);
    }
}

运行这个类的main()方法,我们可以很清楚的看到,代码正确的被执行了:

对于加密解密文件,我们写了一个演示Demo类,来演示这2个操作结果,我们指定原始文件,先用我们的加密方法对其加密,产生密文文件,然后用我们的解密方法解密还原原始文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.charles.encryptstudy;
import java.io.File;
import java.io.FileInputStream;
import java.security.Key;
import javax.crypto.KeyGenerator;
import sun.misc.BASE64Encoder;
/**
 *
 * Description: 这个类是用来演示如何加密和解密文件的
 *
 * @author charles.wang
 * @created Oct 29, 2013 10:06:01 AM
 *
 */
public class EncryptFileDemo {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
                                                                                                      
        //我们演示加密解密文件
        System.out.println("加密解密文件:");
                                                                                                      
        //给定被加密的文件,你可以吧相应任意文件放在任意目录并且更改这里路径
        String filePathNeedEncrypt="travel.jpg";
                                                                                                      
        //获取被加密的文件信息
        File fileNeedEncrypt= new File(filePathNeedEncrypt);
        System.out.println("被加密的文件为:"+fileNeedEncrypt.getName());
        System.out.println("被加密文件的大小为:"+fileNeedEncrypt.length()+" bytes");
                                                                                                      
                                                                                                      
        //产生一个密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("DES");
        Key key=keyGen.generateKey();
        System.out.println("\n加密使用的密钥为:"+(new BASE64Encoder()).encode(key.getEncoded()));
        System.out.println("加密使用的算法为:"+key.getAlgorithm());
                                                                                                      
        //加密文件过程
        System.out.println("\n开始加密文件...");
        String filePathEncrypted="travel-encrypt.encrypt";
        EncryptUtil.encryptFile(filePathNeedEncrypt,filePathEncrypted,key);
                                                                                                      
        //获取加密后的密文文件信息
        File fileEncrypted = new File(filePathEncrypted);
        System.out.println("加密后的密文文件为:"+fileEncrypted.getName());
        System.out.println("加密后的密文文件大小为:"+fileEncrypted.length()+" bytes");
                                                                                                       
                                                                                                      
        //解密文件过程
        System.out.println("\n开始解密文件...");
        String filePathRestored="travel-restored.jpg";
        EncryptUtil.decryptFile(filePathEncrypted,filePathRestored,key);
                                                                                                      
        //获取解密后的明文文件信息
        File fileRestored = new File(filePathRestored);
        System.out.println("解密后的明文文件为:"+fileRestored.getName());
        System.out.println("解密后的明文文件大小为:"+fileRestored.length()+" bytes");
                                                                                                      
    }
                                                                                                  
}

运行这个类的main()方法,我们可以很清楚的看到,代码正确的被执行了,尤其比较下文件大小:

如果不放心的话,我们去文件系统看:

对于原始文件travel.jpg:

对于加密后的密文文件travel-encrypt.encrypt:

再比较解密后还原的文件travel-restored.jpg:

可以发现它和原始文件是完全一样的。

本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1316630,如需转载请自行联系原作者

密码学研究-加密解密相关推荐

  1. DES的加密解密在ECB上的使用(C语言实现)——大三密码学实验

    目录 实验内容 实验原理 DES加密解密 ECB(电码本模式) 代码 DES函数的构建 RE_DES函数的构建 ECB函数的构建 RE_ECB的函数的构建 主函数的构建 总代码 测试结果 实验内容 输 ...

  2. 【密码学Sage代码】椭圆曲线加密/解密(基于《密码编码学与网络安全——原理与实践(第七版)》)

    [密码学Sage代码]椭圆曲线加密/解密(基于<密码编码学与网络安全--原理与实践(第七版)>) 教材内容: 实践的Sage代码: #[静水流深Sage代码]使用椭圆曲线密码体制进行加密/ ...

  3. 凯撒密码加密解密——Java代码(密码学)

    凯撒密码加密解密--Java代码(密码学) 凯撒密码: 恺撒密码(英语:Caesar cipher),或称恺撒加密.恺撒变换.变换加密,是一种最简单且最广为人知的加密技术.它是一种替换加密的技术,明文 ...

  4. 密码学之仿射加密解密算法

    仿射变换的加密解密分别是: c = Ea,b(m)  ≡ a, + b(mod 26) m = Da,b(c) ≡ a^-1(c - b)(mod 26) 其中,a,b是密钥,为满足0≤a,b≤25和 ...

  5. PHP 自己研究的一套 加密 解密 字符串的算法

    <?phpextension_loaded('openssl') or die('php需要openssl扩展支持');$sy = "-----BEGIN PRIVATE KEY--- ...

  6. java中解密技术是什么_详解Java 加密解密技术的分类和归纳

    这篇文章主要介绍了Java加密解密基础分类方法汇总的相关资料,需要的朋友可以参考下 Java 加密解密基础: 密码学是研究编制密码和破译密码的技术科学.研究密码变化的客观规律,应用于编制密码以保守通信 ...

  7. IOS 逆向开发(一)密码学 非对称加密RSA

    IOS 逆向开发(一)密码学 RSA 1. 密码学发展简介 2. 非对称加密RSA产生过程 3. RSA 数学原理 3.1 离散对数问题 3.1.1 原根 3.2 欧拉函数Φ 3.3 欧拉定理 3.4 ...

  8. python rsa加密解密_RSA加密解密(python版)

    RSA的算法涉及三个参数,n.e.d. 其中,n是两个大质数p.q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度. e1和d是一对相关的值,e可以任意取,但要求e与(p-1)*(q-1)互质: ...

  9. Go-ecc加密解密详解与代码

    目录 Ecc概述 历史 密钥对生成 加密算法 解密算法 小结 Ecc的Go实现 crypto/ecdsa 包 crypto/elliptic 包 crypto/rand 包 crypto/x509包 ...

最新文章

  1. 手把手从零开始搭建k8s集群超详细教程
  2. wpf计算字符大小占像素_[读书笔记]《计算机科学速成课》——23 屏幕与2D图像显示...
  3. 如果你铁了心要好好搞科研,我强烈建议你看一下这个帖子
  4. android内置picker控件,android中控件DatePicker控件-Fun言
  5. Openstack_单元测试
  6. FindBugs工具常见问题
  7. linux 切换用户_Linux 用户态切换到内核态的 3 种方式
  8. 七、SpringBoot整合elasticsearch集群
  9. oracle变量名,Oracle中的替换变量,变量名,变量名
  10. 【C语言】三子棋游戏
  11. excelexportentity中设置null不显示的方法_学习笔记-Java中的$符
  12. 一个学习爱好者,应该怎么学习golang
  13. 浏览器内核选型列表,请大家继续补充
  14. z17刷机miui12教程_小米6刷miui12教程
  15. word 插入公式技巧
  16. html入门:网页字体的设置
  17. 土壤水分特征参数估计(soil water characteristic)
  18. Android 文件系统与Android11 分区存储
  19. 微信小程序 - 在自定义组件中请求后端 API 数据接口(引入该组件的页面触发)组件在哪个生命周期钩子函数中请求接口数据呢?
  20. 麒麟Linux系统根目录与单目录扩容详解,适用于大多数的centeros系统

热门文章

  1. [转]编程之美数组分割问题
  2. citrix web Interface5.3 访问WEB网站时,下载本地客户端
  3. poj1019(打表预处理+数学)
  4. win10开机时不显示锁屏壁纸
  5. Python学习记录——函数
  6. spring中的class配置不能使用properties中的字符串
  7. 1.5.2 编译java程序
  8. 如何去掉自动弹出IE9介绍页
  9. “越南QQ”——Zing Chat试玩
  10. NoticeBoard 一个仿原生UI的消息通知控件