java 加解密实例(对称——非对称)

加密算法有很多种:这里只大约列举几例:

1:消息摘要:(数字指纹):既对一个任意长度的一个数据块进行计算,产生一个唯一指纹。MD5/SHA1 发送给其他人你的信息和摘要,其他人用相同的加密方法得到摘要,最后进行比较摘要是否相同。
2:单匙密码体制:DES:比较简便高效,密钥简短,加解密速度快,破译极其困难,但其安全性依赖于密匙的安全性。 DES(Data Encryption Standard)是发明最早的最广泛使用的分组对称加密算法。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密
3:数字签名:就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行RSA算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性)。当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。 代表:DSA
4:非对称密匙密码体制(公匙体系):加密密匙不同于解密密匙,加密密匙公之于众,谁都可以使用,解密密匙只有解密人自己知道。代表:RSA

下面是对上面几个例子进行的简单实现:

 

View Code
  1 package test;
  2 import java.io.FileInputStream;
  3 import java.io.FileOutputStream;
  4 import java.io.IOException;
  5 import java.io.ObjectInputStream;
  6 import java.io.ObjectOutputStream;
  7 import java.security.*;
  8 import javax.crypto.Cipher;
  9 import javax.crypto.KeyGenerator;
 10 import javax.crypto.SecretKey;
 11 /**
 12  * 加密解密
 13  * 
 14  * @author shy.qiu
 15  * @since  http://blog.csdn.net/qiushyfm
 16  */
 17 public class CryptTest {
 18     /**
 19      * 进行MD5加密
 20      * 
 21      * @param info
 22      *            要加密的信息
 23      * @return String 加密后的字符串
 24      */
 25     public String encryptToMD5(String info) {
 26         byte[] digesta = null;
 27         try {
 28             // 得到一个md5的消息摘要
 29             MessageDigest alga = MessageDigest.getInstance("MD5");
 30             // 添加要进行计算摘要的信息
 31             alga.update(info.getBytes());
 32             // 得到该摘要
 33             digesta = alga.digest();
 34         } catch (NoSuchAlgorithmException e) {
 35             e.printStackTrace();
 36         }
 37         // 将摘要转为字符串
 38         String rs = byte2hex(digesta);
 39         return rs;
 40     }
 41     /**
 42      * 进行SHA加密
 43      * 
 44      * @param info
 45      *            要加密的信息
 46      * @return String 加密后的字符串
 47      */
 48     public String encryptToSHA(String info) {
 49         byte[] digesta = null;
 50         try {
 51             // 得到一个SHA-1的消息摘要
 52             MessageDigest alga = MessageDigest.getInstance("SHA-1");
 53             // 添加要进行计算摘要的信息
 54             alga.update(info.getBytes());
 55             // 得到该摘要
 56             digesta = alga.digest();
 57         } catch (NoSuchAlgorithmException e) {
 58             e.printStackTrace();
 59         }
 60         // 将摘要转为字符串
 61         String rs = byte2hex(digesta);
 62         return rs;
 63     }
 64     // //
 65     /**
 66      * 创建密匙
 67      * 
 68      * @param algorithm
 69      *            加密算法,可用 DES,DESede,Blowfish
 70      * @return SecretKey 秘密(对称)密钥
 71      */
 72     public SecretKey createSecretKey(String algorithm) {
 73         // 声明KeyGenerator对象
 74         KeyGenerator keygen;
 75         // 声明 密钥对象
 76         SecretKey deskey = null;
 77         try {
 78             // 返回生成指定算法的秘密密钥的 KeyGenerator 对象
 79             keygen = KeyGenerator.getInstance(algorithm);
 80             // 生成一个密钥
 81             deskey = keygen.generateKey();
 82         } catch (NoSuchAlgorithmException e) {
 83             e.printStackTrace();
 84         }
 85         // 返回密匙
 86         return deskey;
 87     }
 88     /**
 89      * 根据密匙进行DES加密
 90      * 
 91      * @param key
 92      *            密匙
 93      * @param info
 94      *            要加密的信息
 95      * @return String 加密后的信息
 96      */
 97     public String encryptToDES(SecretKey key, String info) {
 98         // 定义 加密算法,可用 DES,DESede,Blowfish
 99         String Algorithm = "DES";
100         // 加密随机数生成器 (RNG),(可以不写)
101         SecureRandom sr = new SecureRandom();
102         // 定义要生成的密文
103         byte[] cipherByte = null;
104         try {
105             // 得到加密/解密器
106             Cipher c1 = Cipher.getInstance(Algorithm);
107             // 用指定的密钥和模式初始化Cipher对象
108             // 参数:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
109             c1.init(Cipher.ENCRYPT_MODE, key, sr);
110             // 对要加密的内容进行编码处理,
111             cipherByte = c1.doFinal(info.getBytes());
112         } catch (Exception e) {
113             e.printStackTrace();
114         }
115         // 返回密文的十六进制形式
116         return byte2hex(cipherByte);
117     }
118     /**
119      * 根据密匙进行DES解密
120      * 
121      * @param key
122      *            密匙
123      * @param sInfo
124      *            要解密的密文
125      * @return String 返回解密后信息
126      */
127     public String decryptByDES(SecretKey key, String sInfo) {
128         // 定义 加密算法,
129         String Algorithm = "DES";
130         // 加密随机数生成器 (RNG)
131         SecureRandom sr = new SecureRandom();
132         byte[] cipherByte = null;
133         try {
134             // 得到加密/解密器
135             Cipher c1 = Cipher.getInstance(Algorithm);
136             // 用指定的密钥和模式初始化Cipher对象
137             c1.init(Cipher.DECRYPT_MODE, key, sr);
138             // 对要解密的内容进行编码处理
139             cipherByte = c1.doFinal(hex2byte(sInfo));
140         } catch (Exception e) {
141             e.printStackTrace();
142         }
143         // return byte2hex(cipherByte);
144         return new String(cipherByte);
145     }
146     // /
147     /**
148      * 创建密匙组,并将公匙,私匙放入到指定文件中
149      * 
150      * 默认放入mykeys.bat文件中
151      */
152     public void createPairKey() {
153         try {
154             // 根据特定的算法一个密钥对生成器
155             KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");
156             // 加密随机数生成器 (RNG)
157             SecureRandom random = new SecureRandom();
158             // 重新设置此随机对象的种子
159             random.setSeed(1000);
160             // 使用给定的随机源(和默认的参数集合)初始化确定密钥大小的密钥对生成器
161             keygen.initialize(512, random);// keygen.initialize(512);
162             // 生成密钥组
163             KeyPair keys = keygen.generateKeyPair();
164             // 得到公匙
165             PublicKey pubkey = keys.getPublic();
166             // 得到私匙
167             PrivateKey prikey = keys.getPrivate();
168             // 将公匙私匙写入到文件当中
169             doObjToFile("mykeys.bat", new Object[] { prikey, pubkey });
170         } catch (NoSuchAlgorithmException e) {
171             e.printStackTrace();
172         }
173     }
174     /**
175      * 利用私匙对信息进行签名 把签名后的信息放入到指定的文件中
176      * 
177      * @param info
178      *            要签名的信息
179      * @param signfile
180      *            存入的文件
181      */
182     public void signToInfo(String info, String signfile) {
183         // 从文件当中读取私匙
184         PrivateKey myprikey = (PrivateKey) getObjFromFile("mykeys.bat", 1);
185         // 从文件中读取公匙
186         PublicKey mypubkey = (PublicKey) getObjFromFile("mykeys.bat", 2);
187         try {
188             // Signature 对象可用来生成和验证数字签名
189             Signature signet = Signature.getInstance("DSA");
190             // 初始化签署签名的私钥
191             signet.initSign(myprikey);
192             // 更新要由字节签名或验证的数据
193             signet.update(info.getBytes());
194             // 签署或验证所有更新字节的签名,返回签名
195             byte[] signed = signet.sign();
196             // 将数字签名,公匙,信息放入文件中
197             doObjToFile(signfile, new Object[] { signed, mypubkey, info });
198         } catch (Exception e) {
199             e.printStackTrace();
200         }
201     }
202     /**
203      * 读取数字签名文件 根据公匙,签名,信息验证信息的合法性
204      * 
205      * @return true 验证成功 false 验证失败
206      */
207     public boolean validateSign(String signfile) {
208         // 读取公匙
209         PublicKey mypubkey = (PublicKey) getObjFromFile(signfile, 2);
210         // 读取签名
211         byte[] signed = (byte[]) getObjFromFile(signfile, 1);
212         // 读取信息
213         String info = (String) getObjFromFile(signfile, 3);
214         try {
215             // 初始一个Signature对象,并用公钥和签名进行验证
216             Signature signetcheck = Signature.getInstance("DSA");
217             // 初始化验证签名的公钥
218             signetcheck.initVerify(mypubkey);
219             // 使用指定的 byte 数组更新要签名或验证的数据
220             signetcheck.update(info.getBytes());
221             System.out.println(info);
222             // 验证传入的签名
223             return signetcheck.verify(signed);
224         } catch (Exception e) {
225             e.printStackTrace();
226             return false;
227         }
228     }
229     /**
230      * 将二进制转化为16进制字符串
231      * 
232      * @param b
233      *            二进制字节数组
234      * @return String
235      */
236     public String byte2hex(byte[] b) {
237         String hs = "";
238         String stmp = "";
239         for (int n = 0; n < b.length; n++) {
240             stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
241             if (stmp.length() == 1) {
242                 hs = hs + "0" + stmp;
243             } else {
244                 hs = hs + stmp;
245             }
246         }
247         return hs.toUpperCase();
248     }
249     /**
250      * 十六进制字符串转化为2进制
251      * 
252      * @param hex
253      * @return
254      */
255     public byte[] hex2byte(String hex) {
256         byte[] ret = new byte[8];
257         byte[] tmp = hex.getBytes();
258         for (int i = 0; i < 8; i++) {
259             ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
260         }
261         return ret;
262     }
263     /**
264      * 将两个ASCII字符合成一个字节; 如:"EF"--> 0xEF
265      * 
266      * @param src0
267      *            byte
268      * @param src1
269      *            byte
270      * @return byte
271      */
272     public static byte uniteBytes(byte src0, byte src1) {
273         byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
274                 .byteValue();
275         _b0 = (byte) (_b0 << 4);
276         byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
277                 .byteValue();
278         byte ret = (byte) (_b0 ^ _b1);
279         return ret;
280     }
281     /**
282      * 将指定的对象写入指定的文件
283      * 
284      * @param file
285      *            指定写入的文件
286      * @param objs
287      *            要写入的对象
288      */
289     public void doObjToFile(String file, Object[] objs) {
290         ObjectOutputStream oos = null;
291         try {
292             FileOutputStream fos = new FileOutputStream(file);
293             oos = new ObjectOutputStream(fos);
294             for (int i = 0; i < objs.length; i++) {
295                 oos.writeObject(objs[i]);
296             }
297         } catch (Exception e) {
298             e.printStackTrace();
299         } finally {
300             try {
301                 oos.close();
302             } catch (IOException e) {
303                 e.printStackTrace();
304             }
305         }
306     }
307     /**
308      * 返回在文件中指定位置的对象
309      * 
310      * @param file
311      *            指定的文件
312      * @param i
313      *            从1开始
314      * @return
315      */
316     public Object getObjFromFile(String file, int i) {
317         ObjectInputStream ois = null;
318         Object obj = null;
319         try {
320             FileInputStream fis = new FileInputStream(file);
321             ois = new ObjectInputStream(fis);
322             for (int j = 0; j < i; j++) {
323                 obj = ois.readObject();
324             }
325         } catch (Exception e) {
326             e.printStackTrace();
327         } finally {
328             try {
329                 ois.close();
330             } catch (IOException e) {
331                 e.printStackTrace();
332             }
333         }
334         return obj;
335     }
336     /**
337      * 测试
338      * 
339      * @param args
340      */
341     public static void main(String[] args) {
342         CryptTest jiami = new CryptTest();
343         // 执行MD5加密"Hello world!"
344         System.out.println("Hello经过MD5:" + jiami.encryptToMD5("Hello"));
345         // 生成一个DES算法的密匙
346         SecretKey key = jiami.createSecretKey("DES");
347         // 用密匙加密信息"Hello world!"
348         String str1 = jiami.encryptToDES(key, "Hello");
349         System.out.println("使用des加密信息Hello为:" + str1);
350         // 使用这个密匙解密
351         String str2 = jiami.decryptByDES(key, str1);
352         System.out.println("解密后为:" + str2);
353         // 创建公匙和私匙
354         jiami.createPairKey();
355         // 对Hello world!使用私匙进行签名
356         jiami.signToInfo("Hello", "mysign.bat");
357         // 利用公匙对签名进行验证。
358         if (jiami.validateSign("mysign.bat")) {
359             System.out.println("Success!");
360         } else {
361             System.out.println("Fail!");
362         }
363     }
364 }

用到的重要的类
javax.crypto.KeyGenerator
public final SecretKey generateKey()生成一个密钥
public static final KeyGenerator getInstance(String algorithm) 返回生成指定算法的秘密密钥的KeyGenerator对象。
javax.crypto 接口 SecretKey
javax.crypto.Cipher 此类为加密和解密提供密码功能。它构成了 Java Cryptographic Extension (JCE) 框架的核心
public final void init(int opmode,Key key)
public final byte[] doFinal(byte[] input) 按单部分操作加密或解密数据,或者结束一个多部分操作
java.security.KeyPairGenerator
static KeyPairGenerator getInstance(String algorithm)
回生成指定算法的 public/private 密钥对的 KeyPairGenerator 对象。
java.security.Signature
使用 Signature 对象签名数据或验证签名包括以下三个阶段:
1:初始化,使用
初始化验证签名的公钥(请参见 initVerify),或使用
初始化签署签名的私钥(也可以选择“安全随机数生成器”)initSign(PrivateKey)和initSign(PrivateKey, SecureRandom))。
2:更新
根据初始化类型,这可更新要签名或验证的字节。请参见 update 方法。
3:签署或验证所有更新字节的签名。请参见 sign 方法和 verify 方法。

转载于:https://www.cnblogs.com/sunfb/archive/2013/02/25/2932084.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非对称加密算法是一种常用的加密方式,它采用了一对密钥,即公钥和私钥。公钥是公开的,可以任意分发,而私钥则只能由密钥的所有者持有,用于解密加密数据。常见的非对称加密算法包括RSA、DSA、ECC等。 下面是一个使用RSA算法实现非对称加密的Java示例代码: ```java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import javax.crypto.Cipher; public class RSAEncryptionExample { public static void main(String[] args) throws Exception { String input = "Hello World!"; KeyPair keyPair = generateRSAKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); byte[] encryptedData = rsaEncrypt(input.getBytes(), publicKey); byte[] decryptedData = rsaDecrypt(encryptedData, privateKey); System.out.println("Original data: " + input); System.out.println("Encrypted data: " + new String(encryptedData)); System.out.println("Decrypted data: " + new String(decryptedData)); } public static KeyPair generateRSAKeyPair() throws Exception { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(2048); // key size KeyPair keyPair = generator.generateKeyPair(); return keyPair; } public static byte[] rsaEncrypt(byte[] data, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedData = cipher.doFinal(data); return encryptedData; } public static byte[] rsaDecrypt(byte[] data, PrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedData = cipher.doFinal(data); return decryptedData; } } ``` 这个示例代码中,我们首先生成了一个RSA密钥对,包括公钥和私钥。然后使用公钥对原始数据进行加密,得到加密后的数据。接着使用私钥对加密后的数据进行解密,得到原始数据。 需要注意的是,RSA算法使用的密钥长度越长,安全性就越高,但加解密的速度也越慢。在实际应用中,需要根据实际需求和环境选择合适的密钥长度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值