zoukankan      html  css  js  c++  java
  • [转] 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

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

    Java代码 
    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. }  
  • 相关阅读:
    深入理解Azure自动扩展集VMSS(1)
    使用ARM和VMSS创建自动扩展的web集群
    使用ARM模板部署自动扩展的Linux VMSS(2)
    使用ARM模板部署自动扩展的Linux VMSS(1)
    Azure上A/D系列虚拟机到DS系列迁移(2)
    ORM进阶操作
    Django之中间件
    restful十项规范
    同源策略与跨域请求
    Django之CSRF问题
  • 原文地址:https://www.cnblogs.com/Gile/p/3996212.html
Copyright © 2011-2022 走看看