范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Java中常用的加密方式(附多个工具类)

  一、Java常用加密方式Base64加密算法(编码方式)  MD5加密(消息摘要算法,验证信息完整性)  对称加密算法  非对称加密算法  数字签名算法  数字证书
  二、分类
  按加密算法是否需要key被分为两类:  不基于key的有: Base64算法、MD5  基于key的有: 对称加密算法、非对称加密算法、数字签名算法、数字证书、HMAC、RC4(对称加密)
  按加密算法是否可逆被分为两类:  单向加密算法(不可解密):MD5、SHA、HMAC  非单项加密算法(可解密):BASE64、对称加密算法、非对称加密算法、数字签名算法、数字证书
  三、算法介绍
  1.对称加密
  对称加密是最快速、最简单的一种加密方式, 加密(encryption)与解密(decryption)用的是同样的密钥(secret key) 。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。
  对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off。
  DES (Data Encryption Standard)和 TripleDES 是对称加密的两种实现。
  DES和TripleDES基本算法一致,只是TripleDES算法提供的key位数更多,加密可靠性更高。
  DES使用的密钥key为8字节,初始向量IV也是8字节。
  TripleDES使用24字节的key,初始向量IV也是8字节。
  两种算法都是以8字节为一个块进行加密,一个数据块一个数据块的加密,一个8字节的明文加密后的密文也是8字节。如果明文长度不为8字节的整数倍,添加值为0的字节凑满8字节整数倍。所以加密后的密文长度一定为8字节的整数倍
  下面举个例子:  import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException;   import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec;   import org.apache.commons.codec.binary.Base64;   public class DESDemo {     // 算法名称     public static final String KEY_ALGORITHM = "DES";     // 算法名称/加密模式/填充方式     // DES共有四种工作模式-->>ECB:电子密码本模式、CBC:加密分组链接模式、CFB:加密反馈模式、OFB:输出反馈模式     public static final String CIPHER_ALGORITHM = "DES/ECB/NoPadding";       /**      *      * 生成密钥key对象      *      * @param KeyStr      *            密钥字符串      * @return 密钥对象      * @throws InvalidKeyException      * @throws NoSuchAlgorithmException      * @throws InvalidKeySpecException      * @throws Exception      */     private static SecretKey keyGenerator(String keyStr) throws Exception {         byte input[] = HexString2Bytes(keyStr);         DESKeySpec desKey = new DESKeySpec(input);         // 创建一个密匙工厂,然后用它把DESKeySpec转换成         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");         SecretKey securekey = keyFactory.generateSecret(desKey);         return securekey;     }       private static int parse(char c) {         if (c >= "a")             return (c - "a" + 10) & 0x0f;         if (c >= "A")             return (c - "A" + 10) & 0x0f;         return (c - "0") & 0x0f;     }       // 从十六进制字符串到字节数组转换     public static byte[] HexString2Bytes(String hexstr) {         byte[] b = new byte[hexstr.length() / 2];         int j = 0;         for (int i = 0; i < b.length; i++) {             char c0 = hexstr.charAt(j++);             char c1 = hexstr.charAt(j++);             b[i] = (byte) ((parse(c0) << 4) | parse(c1));         }         return b;     }       /**      * 加密数据      *      * @param data      *            待加密数据      * @param key      *            密钥      * @return 加密后的数据      */     public static String encrypt(String data, String key) throws Exception {         Key deskey = keyGenerator(key);         // 实例化Cipher对象,它用于完成实际的加密操作         Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);         SecureRandom random = new SecureRandom();         // 初始化Cipher对象,设置为加密模式         cipher.init(Cipher.ENCRYPT_MODE, deskey, random);         byte[] results = cipher.doFinal(data.getBytes());         // 该部分是为了与加解密在线测试网站(http://tripledes.online-domain-tools.com/)的十六进制结果进行核对         for (int i = 0; i < results.length; i++) {             System.out.print(results[i] + " ");         }         System.out.println();         // 执行加密操作。加密后的结果通常都会用Base64编码进行传输         return Base64.encodeBase64String(results);     }       /**      * 解密数据      *      * @param data      *            待解密数据      * @param key      *            密钥      * @return 解密后的数据      */     public static String decrypt(String data, String key) throws Exception {         Key deskey = keyGenerator(key);         Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);         // 初始化Cipher对象,设置为解密模式         cipher.init(Cipher.DECRYPT_MODE, deskey);         // 执行解密操作         return new String(cipher.doFinal(Base64.decodeBase64(data)));     }       public static void main(String[] args) throws Exception {         String source = "helloittx";         System.out.println("原文: " + source);         String key = "A1B2C3D4E5F60708";         String encryptData = encrypt(source, key);         System.out.println("加密后: " + encryptData);         String decryptData = decrypt(encryptData, key);         System.out.println("解密后: " + decryptData);     } } 2.非对称加密
  非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥(public key)和私钥(private key)。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥。比如,你向银行请求公钥,银行将公钥发给你,你使用公钥对消息加密,那么只有私钥的持有人–银行才能对你的消息解密。与对称加密不同的是,银行不需要将私钥通过网络发送出去,因此安全性大大提高。
  目前最常用的非对称加密算法是RSA算法,是Rivest, Shamir, 和Adleman于1978年发明,他们那时都是在MIT。请看下面的例子:  import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec;   import javax.crypto.Cipher;   import com.lxh.rsatest.HexUtil;   import Decoder.BASE64Decoder; import Decoder.BASE64Encoder;   public class RSAEncrypt {     /** 指定加密算法为DESede */     private static String ALGORITHM = "RSA";     /** 指定key的大小 */     private static int KEYSIZE = 1024;     /** 指定公钥存放文件 */     private static String PUBLIC_KEY_FILE = "public.keystore";     /** 指定私钥存放文件 */     private static String PRIVATE_KEY_FILE = "private.keystore";       /**      * 生成密钥对      */     private static void generateKeyPair() throws Exception {         /** RSA算法要求有一个可信任的随机数源 */         SecureRandom sr = new SecureRandom();         /** 为RSA算法创建一个KeyPairGenerator对象 */         KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);         /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */         kpg.initialize(KEYSIZE, sr);         /** 生成密匙对 */         KeyPair kp = kpg.generateKeyPair();         /** 得到公钥 */         Key publicKey = kp.getPublic();         /** 得到私钥 */         Key privateKey = kp.getPrivate();         /** 用对象流将生成的密钥写入文件 */         ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));         ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));         oos1.writeObject(publicKey);         oos2.writeObject(privateKey);         /** 清空缓存,关闭文件输出流 */         oos1.close();         oos2.close();     }       /**      * 生成密钥对字符串      */     private static void generateKeyPairString() throws Exception {         /** RSA算法要求有一个可信任的随机数源 */         SecureRandom sr = new SecureRandom();         /** 为RSA算法创建一个KeyPairGenerator对象 */         KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);         /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */         kpg.initialize(KEYSIZE, sr);         /** 生成密匙对 */         KeyPair kp = kpg.generateKeyPair();         /** 得到公钥 */         Key publicKey = kp.getPublic();         /** 得到私钥 */         Key privateKey = kp.getPrivate();         /** 用字符串将生成的密钥写入文件 */           String algorithm = publicKey.getAlgorithm(); // 获取算法         KeyFactory keyFact = KeyFactory.getInstance(algorithm);         BigInteger prime = null;         BigInteger exponent = null;           RSAPublicKeySpec keySpec = (RSAPublicKeySpec) keyFact.getKeySpec(publicKey, RSAPublicKeySpec.class);           prime = keySpec.getModulus();         exponent = keySpec.getPublicExponent();         System.out.println("公钥模量:" + HexUtil.bytes2Hex(prime.toByteArray()));         System.out.println("公钥指数:" + HexUtil.bytes2Hex(exponent.toByteArray()));           System.out.println(privateKey.getAlgorithm());         RSAPrivateCrtKeySpec privateKeySpec = (RSAPrivateCrtKeySpec) keyFact.getKeySpec(privateKey,                 RSAPrivateCrtKeySpec.class);         BigInteger privateModulus = privateKeySpec.getModulus();         BigInteger privateExponent = privateKeySpec.getPrivateExponent();           System.out.println("私钥模量:" + HexUtil.bytes2Hex(privateModulus.toByteArray()));         System.out.println("私钥指数:" + HexUtil.bytes2Hex(privateExponent.toByteArray()));       }       /**      * 加密方法 source: 源数据      */     public static String encrypt(String source) throws Exception {         generateKeyPair();         /** 将文件中的公钥对象读出 */         ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));         Key key = (Key) ois.readObject();         ois.close();           String algorithm = key.getAlgorithm(); // 获取算法         KeyFactory keyFact = KeyFactory.getInstance(algorithm);         BigInteger prime = null;         BigInteger exponent = null;         if ("RSA".equals(algorithm)) { // 如果是RSA加密             RSAPublicKeySpec keySpec = (RSAPublicKeySpec) keyFact.getKeySpec(key, RSAPublicKeySpec.class);             prime = keySpec.getModulus();             exponent = keySpec.getPublicExponent();   //          System.out.println("公钥模量:" + HexUtil.bytes2Hex(prime.toByteArray())); //          System.out.println("公钥指数:" + HexUtil.bytes2Hex(exponent.toByteArray()));           }           /** 得到Cipher对象来实现对源数据的RSA加密 */         Cipher cipher = Cipher.getInstance(ALGORITHM);         cipher.init(Cipher.ENCRYPT_MODE, key);         byte[] b = source.getBytes();         /** 执行加密操作 */         byte[] b1 = cipher.doFinal(b);         BASE64Encoder encoder = new BASE64Encoder();         return encoder.encode(b1);     }       /**      * 解密算法 cryptograph:密文      */     public static String decrypt(String cryptograph) throws Exception {         /** 将文件中的私钥对象读出 */         ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));         Key key = (Key) ois.readObject();           String algorithm = key.getAlgorithm(); // 获取算法         KeyFactory keyFact = KeyFactory.getInstance(algorithm);         RSAPrivateCrtKeySpec privateKeySpec = (RSAPrivateCrtKeySpec) keyFact.getKeySpec(key,                 RSAPrivateCrtKeySpec.class);         BigInteger privateModulus = privateKeySpec.getModulus();         BigInteger privateExponent = privateKeySpec.getPrivateExponent();   //      System.out.println("私钥模量:" + HexUtil.bytes2Hex(privateModulus.toByteArray())); //      System.out.println("私钥指数:" + HexUtil.bytes2Hex(privateExponent.toByteArray()));           /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */         Cipher cipher = Cipher.getInstance(ALGORITHM);         cipher.init(Cipher.DECRYPT_MODE, key);         BASE64Decoder decoder = new BASE64Decoder();           byte[] b1 = decoder.decodeBuffer(cryptograph);         /** 执行解密操作 */         byte[] b = cipher.doFinal(b1);         return new String(b);     }       public static void main(String[] args) throws Exception {         generateKeyPair(); //生成文件形式公钥和私钥         //generateKeyPairString();//生成字符串形式公钥和私钥           String source = "非对称加密RSA";// 要加密的字符串           String cryptograph = encrypt(source);// 生成的密文         String hexCrypt = HexUtil.bytes2Hex(cryptograph.getBytes(), false);         System.out.println("生成的密文--->" + hexCrypt);           String target = decrypt(HexUtil.hex2String(hexCrypt));// 解密密文         System.out.println("解密密文--->" + target);       } }
  虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去。
  (1) 对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。
  (2) 非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。
  (3) 解决的办法是将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。
  3.Base64编码
  Base 64 Encoding有什么用?举个简单的例子,你使用SMTP协议 (Simple Mail Transfer Protocol 简单邮件传输协议)来发送邮件。因为这个协议是基于文本的协议,所以如果邮件中包含一幅图片,我们知道图片的存储格式是二进制数据(binary data),而非文本格式,我们必须将二进制的数据编码成文本格式,这时候Base 64 Encoding就派上用场了。  public void testJDKBase64(){     String encoderStr = java.util.Base64.getEncoder().encodeToString(s.getBytes());     System.out.println("encode :"+encoderStr);       String decodeStr = new String(java.util.Base64.getDecoder().decode(encoderStr));     System.out.println("decodeStr :"+decodeStr); }   public void testCodecBase64(){     String encoderStr = org.apache.commons.codec.binary.Base64.encodeBase64String(s.getBytes());     System.out.println("encode :"+encoderStr);       String decodeStr = new String(org.apache.commons.codec.binary.Base64.decodeBase64(encoderStr));     System.out.println("decodeStr :"+decodeStr); }
  附工具类  package com.hl.bluetooth.util;  import org.springframework.boot.system.ApplicationHome; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder;  import java.io.*; import java.util.Objects;  /**  * @DateL 2021/11/16 15:09  * @ClassName: FileUtils  **/ @Component public class FileUtils {       public static File multipartFileToFile(MultipartFile multipartFile) {         File file = new File(Objects.requireNonNull(multipartFile.getOriginalFilename()));         try {             InputStream ins = null;             ins = multipartFile.getInputStream();             OutputStream os = new FileOutputStream(file);             int bytesRead = 0;             byte[] buffer = new byte[8192];             while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {                 os.write(buffer, 0, bytesRead);             }             os.close();             ins.close();         } catch (Exception e) {             e.printStackTrace();         }         return file;     }      /**      * 图片转化成base64字符串      *      */     public static String getImageStr(String imgPath) {         InputStream in = null;         byte[] data = null;         String encode = null;         // 对字节数组Base64编码         BASE64Encoder encoder = new BASE64Encoder();         try {             // 读取图片字节数组             in = new FileInputStream(imgPath);             data = new byte[in.available()];             in.read(data);             encode = encoder.encode(data);         } catch (IOException e) {             e.printStackTrace();         } finally {             try {                 in.close();             } catch (IOException e) {                 e.printStackTrace();             }         }         return encode;     }      /**      * base64字符串转化成图片      *      * @param imgData     图片编码      */     public static String generateImage(String imgData, String fileName)  {         if (imgData == null) {             // 图像数据为空             return "null";         }         ApplicationHome applicationHome = new ApplicationHome(FileUtils.class);         File source = applicationHome.getSource();         String dirPath = source.getParentFile().toString() + "/upload";         BASE64Decoder decoder = new BASE64Decoder();          File dir = new File(dirPath);         if (!dir.exists()){             dir.mkdirs();         }         File file = new File(dirPath+"/"+fileName);         if (file.exists()){             file.delete();         }         try {             // Base64解码             byte[] b = decoder.decodeBuffer(imgData);             for (int i = 0; i < b.length; ++i) {                 // 调整异常数据                 if (b[i] < 0) {                     b[i] += 256;                 }             }             OutputStream out = new FileOutputStream(dirPath+""+fileName);             out.write(b);             out.flush();             out.close();             return dirPath+""+fileName;         } catch (Exception e) {             e.printStackTrace();             return "null";         }     }     }
  4.MD5加密
  Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992).
  MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。
  MD5用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。
  MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。  import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;   /**  * Java消息摘要算法 MD5 工具类,其实其他摘要算法的实现也类似  */ public class MD5Util {     /**      * 对文本执行 md5 摘要加密, 此算法与 mysql,JavaScript生成的md5摘要进行过一致性对比.      * @param plainText      * @return 返回值中的字母为小写      */     public static String md5(String plainText) {         if (null == plainText) {             plainText = "";         }         String MD5Str = "";         try {             // JDK 6 支持以下6种消息摘要算法,不区分大小写             // md5,sha(sha-1),md2,sha-256,sha-384,sha-512             MessageDigest md = MessageDigest.getInstance("MD5");             md.update(plainText.getBytes());             byte b[] = md.digest();               int i;               StringBuilder builder = new StringBuilder(32);             for (int offset = 0; offset < b.length; offset++) {                 i = b[offset];                 if (i < 0)                     i += 256;                 if (i < 16)                     builder.append("0");                 builder.append(Integer.toHexString(i));             }             MD5Str = builder.toString();             // LogUtil.println("result: " + buf.toString());// 32位的加密         } catch (NoSuchAlgorithmException e) {             e.printStackTrace();         }         return MD5Str;     }     // 一个简版测试     public static void main(String[] args) {         String m1 = md5("1");         String m2 = md5(m1);         /* 输出为          * m1=c4ca4238a0b923820dcc509a6f75849b          * m2=28c8edde3d61a0411511d3b1866f0636          */         System.out.println("m1="+m1);         System.out.println("m2="+m2);     } }
  通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给Base64再加密一把,得到相应的字符串。
  5.数字签名算法
  签名:就有安全性,抗否认性
  数字签名:带有密钥(公钥,私钥)的消息摘要算法
  作用:
  1. 验证数据的完整性
  2. 认证数据来源
  3. 抗否认
  数字签名遵循:私钥签名,公钥验证
  常用的数字签名算法:RSA,DSA,ECDSA
  RSA介绍:
  是经典算法,是目前为止使用最广泛的数字签名算法。
  RSA数字签名算法的密钥实现与RSA的加密算法是一样的,算法的名称都叫RSA。密钥的产生和转换都是一样的。
  RSA数字签名算法主要包括MD和SHA两类。  import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;   import org.apache.commons.codec.binary.Hex;   public class RSATest {     public static final String src = "hello world";       public static void main(String[] args) {         jdkRSA();       }       /**      * 说明: 用java的jdk里面相关方法实现rsa的签名及签名验证      */     public static void jdkRSA() {         try {             // 1.初始化密钥             KeyPairGenerator keyPairGenerator = KeyPairGenerator                     .getInstance("RSA");             //设置KEY的长度             keyPairGenerator.initialize(512);             KeyPair keyPair = keyPairGenerator.generateKeyPair();             //得到公钥             RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();             //得到私钥             RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();               // 2.进行签名             //用私钥进行签名             PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(                     rsaPrivateKey.getEncoded());             KeyFactory keyFactory = KeyFactory.getInstance("RSA");             //构造一个privateKey             PrivateKey privateKey = keyFactory                     .generatePrivate(pkcs8EncodedKeySpec);             //声明签名的对象             Signature signature = Signature.getInstance("MD5withRSA");             signature.initSign(privateKey);             signature.update(src.getBytes());             //进行签名             byte[] result = signature.sign();             System.out.println("jdk rsa sign:" + Hex.encodeHexString(result));               // 3.验证签名             //用公钥进行验证签名             X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(                     rsaPublicKey.getEncoded());             keyFactory = KeyFactory.getInstance("RSA");             //构造一个publicKey             PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);             //声明签名对象             signature = Signature.getInstance("MD5withRSA");             signature.initVerify(publicKey);             signature.update(src.getBytes());             //验证签名             boolean bool = signature.verify(result);             System.out.println("jdk rsa verify:" + bool);         } catch (Exception e) {             System.out.println(e.toString());         }       }   }
  四、应用场景
  Base64应用场景:图片转码(应用于邮件,img标签,http加密)
  MD5应用场景:密码加密、imei加密、文件校验
  非对称加密:电商订单付款、银行相关业务  五、附多个工具类AESpackage com.hl.bluetooth.util;   import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.codec.binary.Base64;  import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec;  public class AesEncryptUtil {     //使用AES-128-CBC加密模式,key需要为16位,key和iv可以相同!     private final static String KEY = "ABCDEF1234432100";     private final static String IV = "43211234DCAB6789";                 /**      * 加密方法      * @param data  要加密的数据      * @param key 加密key      * @param iv 加密iv      * @return 加密的结果      * @throws Exception      */     public static String encrypt(String data, String key, String iv) throws Exception {         try {               Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//"算法/模式/补码方式"NoPadding PkcsPadding             int blockSize = cipher.getBlockSize();               byte[] dataBytes = data.getBytes();             int plaintextLength = dataBytes.length;             if (plaintextLength % blockSize != 0) {                 plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));             }               byte[] plaintext = new byte[plaintextLength];             System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);               SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");             IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());               cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);             byte[] encrypted = cipher.doFinal(plaintext);               return new Base64().encodeToString(encrypted);           } catch (Exception e) {             e.printStackTrace();             return null;         }     }       /**      * 解密方法      * @param data 要解密的数据      * @param key  解密key      * @param iv 解密iv      * @return 解密的结果      * @throws Exception      */     public static String desEncrypt(String data, String key, String iv) throws Exception {         try { //            byte[] encrypted1 = new Base64().decode(data);             byte[] encrypted1 = parseHexStr2Byte(data);  //            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");             SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");             IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());               cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);               byte[] original = cipher.doFinal(encrypted1);             String originalString = new String(original);             return originalString;         } catch (Exception e) {             e.printStackTrace();             return null;         }     }           /**      * 使用默认的key和iv加密      * @param data      * @return      * @throws Exception      */     public static String encrypt(String data) throws Exception {         return encrypt(data, KEY, IV);     }           /**      * 使用默认的key和iv解密      * @param data      * @return      * @throws Exception      */     public static String desEncrypt(String data) throws Exception {          if (StringUtils.isEmpty(data)) {             return null;         }         return desEncrypt(data, KEY, IV);     }      /**      * @Author wdc      * @Description 16进制转byte数组      * @Date 2021/4/19 11:14      * @Param [hexStr]      * @return byte[]      **/     public static byte[] parseHexStr2Byte(String hexStr) {         if (hexStr.length() < 1)             return null;         byte[] result = new byte[hexStr.length()/2];         for (int i = 0;i< hexStr.length()/2; i++) {             int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);             int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);             result[i] = (byte) (high * 16 + low);         }         return result;     }      public static void main(String[] args) { //        String test = "{"admin","admin"}"; ////         String test =new String(test1.getBytes(),"UTF-8"); //       String data = null; //       data = AesEncryptUtil.encrypt(test); //       System.out.println("数据:"+test); //       System.out.println("加密:"+data); //       String jiemi = AesEncryptUtil.desEncrypt(data); //       System.out.println("解密:"+jiemi);     } } base64 package com.sgitg.util;  import java.io.UnsupportedEncodingException;  import org.springframework.util.Base64Utils;  public class Base64Util {      /**      * 解码base64编码的字符串      *       * @param source      * @return      * @throws UnsupportedEncodingException      */     public static String decodeFromString(String source) {         String str = "";         try {             byte[] bt = Base64Utils.decodeFromString(source);             str = new String(bt, "utf-8");         } catch (UnsupportedEncodingException e) {             e.printStackTrace(); // To change body of catch statement use File |                                     // Settings | File Templates.         }         return str;     }      /**      * 对字符串进行base64编码      *       * @param source      * @return      * @throws UnsupportedEncodingException      */     public static String encodeToString(String source) {         byte[] bt = new byte[0];         try {             bt = source.getBytes("utf-8");         } catch (UnsupportedEncodingException e) {             e.printStackTrace(); // To change body of catch statement use File |                                     // Settings | File Templates.         }         return Base64Utils.encodeToString(bt);     } } EncryptUtils (编码集合)* 1、Base64编码 * 1、AES、DES可逆算法 * 2、md5,Hex,Sha不可逆算法加密 package com.sgitg.util;  import org.apache.commons.codec.digest.DigestUtils;  import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Base64; import java.util.zip.CRC32;  /**  * 数据加密  * 继承org.apache.commons.codec.digest.DigestUtils  * 1、Base64编码  * 1、AES、DES可逆算法  * 2、md5,Hex,Sha不可逆算法加密  *  * @author liuyadu  */ public class EncryptUtils extends DigestUtils {     /**      * 计算大文件 md5获取getMD5(); SHA1获取getSha1() CRC32获取 getCRC32()      */     private static char[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e",             "f"};      // 测试     public static void main(String[] args) {         String en = encryptDES("hahahaha", "yaer");         String de = decryptDES("kzWPLLyAsDeBr84lL2COsA==", "yaer");         System.out.println(de);         System.out.println(en);          en = encryptAES("hahahaha", "yaer");         de = decryptAES("FBC82B89BAA1FBBDF3AE086A09D57E7C", "yaer");         System.out.println(de);         System.out.println(en);     }      /**      * AES加密(可逆)      *      * @param plainText  明文      * @param privateKey 密钥      * @return      * @throws NoSuchAlgorithmException      */     public static String encryptAES(String plainText, String privateKey) {         try {             KeyGenerator kgen = KeyGenerator.getInstance("AES");              SecureRandom random = SecureRandom.getInstance("SHA1PRNG");             random.setSeed(privateKey.getBytes());             kgen.init(128, random);              SecretKey secretKey = kgen.generateKey();             byte[] enCodeFormat = secretKey.getEncoded();             SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");             Cipher cipher = Cipher.getInstance("AES");             byte[] byteContent = plainText.getBytes("utf-8");             cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);             byte[] byteRresult = cipher.doFinal(byteContent);             String sb = new String("");              for (int i = 0; i < byteRresult.length; i++) {                 String hex = Integer.toHexString(byteRresult[i] & 0xFF);                 if (hex.length() == 1) {                     hex = "0" + hex;                 }                 sb = sb.concat(hex.toUpperCase());             }             return sb;         } catch (Exception e) {             return null;         }     }      /**      * AES解密      *      * @param cipherText 密文      * @param privateKey 密钥      * @return      * @throws Exception      */     public static String decryptAES(String cipherText, String privateKey) {         try {             if (cipherText.length() < 1) {                 return null;             }             byte[] byteRresult = new byte[cipherText.length() / 2];             for (int i = 0; i < cipherText.length() / 2; i++) {                 int high = Integer.parseInt(cipherText.substring(i * 2, i * 2 + 1), 16);                 int low = Integer.parseInt(cipherText.substring(i * 2 + 1, i * 2 + 2), 16);                 byteRresult[i] = (byte) (high * 16 + low);             }             KeyGenerator kgen = KeyGenerator.getInstance("AES");             SecureRandom random = SecureRandom.getInstance("SHA1PRNG");             random.setSeed(privateKey.getBytes());             kgen.init(128, random);             SecretKey secretKey = kgen.generateKey();             byte[] enCodeFormat = secretKey.getEncoded();             SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");             Cipher cipher = Cipher.getInstance("AES");             cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);             byte[] result = cipher.doFinal(byteRresult);             return new String(result);         } catch (Exception e) {             return null;         }     }      /**      * 加密DES(可逆)      *      * @param plainText  明文      * @param privateKey 密钥      * @return      */     public static String encryptDES(String plainText, String privateKey) {         try {             KeyGenerator keygen = KeyGenerator.getInstance("DES");             SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");             secureRandom.setSeed(privateKey.getBytes());              keygen.init(56, secureRandom);             SecretKey secretKey = keygen.generateKey();              Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");             cipher.init(Cipher.ENCRYPT_MODE, secretKey);             byte[] cipherBytes = cipher.doFinal(plainText.getBytes("utf-8"));             byte[] plainTextBytes = Base64.getEncoder().encode(cipherBytes);              return new String(plainTextBytes, "utf-8");         } catch (Exception e) {             e.printStackTrace();             return null;         }     }      /**      * 解密DES      *      * @param cipherText 密文      * @param privateKey 密钥      * @return      */     public static String decryptDES(String cipherText, String privateKey) {         try {             KeyGenerator keygen = KeyGenerator.getInstance("DES");             SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");             secureRandom.setSeed(privateKey.getBytes());              keygen.init(56, secureRandom);             SecretKey secretKey = keygen.generateKey();              Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");             cipher.init(Cipher.DECRYPT_MODE, secretKey);              byte[] cipherTextBytes = Base64.getDecoder().decode(cipherText.getBytes("utf-8"));             byte[] cipherBytes = cipher.doFinal(cipherTextBytes);              return new String(cipherBytes, "utf-8");         } catch (Exception e) {             e.printStackTrace();             return null;         }     }       /**      * 获取文件md5值      *      * @return md5串      */     public static String md5(File file) {         try {             //encrypt             MessageDigest messagedigest = MessageDigest.getInstance("MD5");             FileInputStream in = new FileInputStream(file);             FileChannel ch = in.getChannel();             MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());             messagedigest.update(byteBuffer);             return bufferToHex(messagedigest.digest());         } catch (Exception e) {             return null;         }      }      /***      * 获取文件SHA1值      *      * @return String 适用于上G大的文件      */     public static String sha1(File file) {         try {             MessageDigest messagedigest = MessageDigest.getInstance("SHA-1");             FileInputStream in = new FileInputStream(file);             FileChannel ch = in.getChannel();             MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());             messagedigest.update(byteBuffer);             return bufferToHex(messagedigest.digest());         } catch (Exception e) {             return null;         }     }      /**      * 获取文件SHA256值      *      * @return String      */     public static String sha256(File file) {         try {             MessageDigest messagedigest = MessageDigest.getInstance("SHA-256");             FileInputStream in = new FileInputStream(file);             FileChannel ch = in.getChannel();             MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());             messagedigest.update(byteBuffer);             return bufferToHex(messagedigest.digest());         } catch (Exception e) {             return null;         }     }      /**      * 获取文件CRC32码      *      * @return String      */     public static String crc32(File file) {         CRC32 crc32 = new CRC32();         // MessageDigest.get         FileInputStream fileInputStream = null;         try {             fileInputStream = new FileInputStream(file);             byte[] buffer = new byte[8192];             int length;             while ((length = fileInputStream.read(buffer)) != -1) {                 crc32.update(buffer, 0, length);             }             return crc32.getValue() + "";         } catch (FileNotFoundException e) {             e.printStackTrace();             return null;         } catch (IOException e) {             e.printStackTrace();             return null;         } finally {             try {                 if (fileInputStream != null) {                     fileInputStream.close();                 }             } catch (IOException e) {                 e.printStackTrace();             }         }     }      /**      * 计算二进制数据      *      * @return      */     private static String bufferToHex(byte bytes[]) {         return bufferToHex(bytes, 0, bytes.length);     }      private static String bufferToHex(byte bytes[], int m, int n) {         StringBuffer stringbuffer = new StringBuffer(2 * n);         int k = m + n;         for (int l = m; l < k; l++) {             appendHexPair(bytes[l], stringbuffer);         }         return stringbuffer.toString();     }      private static void appendHexPair(byte bt, StringBuffer stringbuffer) {         char c0 = hexDigits[(bt & 0xf0) >> 4];         char c1 = hexDigits[bt & 0xf];         stringbuffer.append(c0);         stringbuffer.append(c1);     }   }

儿童彩妆,财富新密码?作者小铁锹原创财经小锄头(chutou0325)还记得小时候用凤仙花的花瓣,小心翼翼包裹着指甲,希望指甲被染成漂亮的红色么?现在的孩子已经不再需要去找凤仙花了,他们很多人已经拥有了虾米关停,字节开张?作者阿鲲来源财经小锄头(IDchutou0325)(来源字节跳动)据Tech星球消息,字节跳动在今年已成立了音乐事业部,这表明字节跳动向流媒体音乐领域更进一步。在今年2月5日,流媒哈啰幸存者,心比天高作者史蒂芬原创财经小锄头(chutou0325)2017年9月,戴威的ofo上线了微信小程序。蚂蚁金服高层知道后很生气,阿里随即派了专人从杭州飞到北京,告诉戴威马上将ofo的微信小看清本质法国电信挺华为背后的小啾啾华为在5G专利数量质量上优势还是很明显的,而且在通信领域深耕多年,厘米波5G也是当下来讲普及的综合效果更好的方案,但这几年,以老美为首的小圈子对中国高科企业围追堵截,小弟们更是背后5199元的精致极品iPhone13mini网友入手几天,4600元忍痛出手精致极品iPhone13mini网友入手几天,为何忍痛出手这位网友前几天刚入手的iPhone13mini,忍不住和大家分享一下体验,主要问题还是在实用性方面已不符合目前智能手机的水去海南免税店买iPhone13能否省下一张机票,真相如下随着国内疫情控制稳定,出门旅行的人数也在增长,例如国庆假期就有很多朋友出行,其中极富东南亚旅游其情调的海南岛就成为不少人的首选,离岛免税店当然对游客的魅力也很大,海南自贸港在海南目年轻人最喜爱的idol产品力如何?华为nova9系列正式发布9月23日,华为nova9系列正式发布。nova9系列在产品设计方面,依旧表现出了华为的实力和风采,密集的设计工艺突破黑科技发布独家创新的功能等,都让人看到了一款真正的旗舰的影子。年轻人的酒文化,度数越来越低作者秦沁原创深眸财经(chutou0325)年轻人到底爱不爱喝酒?前段时间阿里事件爆发,恶臭的酒桌文化成为众矢之的,年轻人就职场喝酒表达自己的看法,纷纷表示已经将饮酒二字拉入黑名单让年轻人睡个好觉,喜临门成Z世代新宠作者易牟原创深眸财经(chutou0325)近日,喜临门发布2021年半年度财报。报告显示,2021年上半年喜临门的营收达31。07亿元,较上年同比增长57。25归母净利润达到2。二手奢侈品的刀,割向了年轻人的钱包作者易牟原创深眸财经(chutou0325)最近热播剧我在他乡挺好的第一集,就讲到了主角之一的许言逛中古店,准备用攒下的工资给好朋友晶晶买一个二手的Gucci,结尾许言又一次光顾中股价最高的自动驾驶企业入局造车,锦上添花还是浪费时间?据可靠消息称,自动驾驶的巨头小马智行有加入造车的赛道的种种痕迹。作为国内估值最高的自动驾驶企业,小马智行已经在中国北京广州上海及美国硅谷均建有研发中心并进行测试,在中国广州以及美国
库克出刀精准!iPhone13Pro系列今年可能会取消256GB存储规格Iphone13要发布了我们的库克先生也要开始整活了,据多方爆料今年的iPhone13Pro系列居然要取消256GB存储规格就我一个买手机只买256g的吗?128g的不够用,512工信部辛国斌提高锂钴镍保障体系,研发新能源汽车安全标准第十七届中国汽车产业发展(泰达)国际论坛开幕大会上,工业和信息化部副部长辛国斌表示,今年是十四五规划的开局之年,做好后续汽车产业发展工作意义重大。发挥部级联席会议制度,统筹加快新能骨声纹耳机,厉害在哪里?骨声纹耳机,厉害在哪里?发布时间11小时前AirPods有多方便已经很深入人心了,它在几乎是颠覆了蓝牙耳机在苹果生态系统中的使用习惯。也成为了苹果历史上第二畅销的产品。而今天我们介苏宁收购万达百货续已接手运营,4月将完成交割新京报讯(记者陈维城)4月10日,据苏宁内部知情人士透露,三十多位万达百货总经理抵达南京苏宁总部,他们此行是参加苏宁时尚百货集团的月度例会。这意味着苏宁易购管理团队已全面接手万达百网红张大奕,华尔街登场遭打脸,颜值支撑不起市值不是每种成功都能够仿效,不是每种成功都值得仿效。遇言姐4月3日,号称国内网红电商第一股的如涵,在纳斯达克上市,总发行规模为1。25亿美元。持股15的网红张大奕小姐上市敲钟,就在10AMD发布4款15W新锐龙CPU强8代i72。5倍!AMD发布面向移动笔记本平台的AMDRyzenPRO3000系列(第二代)和AthlonPRO商用处理器。家族包含四款新品,分别AMDRyzen7PRO3700UAMDRyzen5又出了一种养老新模式能把养老院搬回家!设置家庭养老床位智慧养老的时代来临。前不久,武汉市首次提出开设家庭养老床位。家庭养老床位就是养老机构将养老床位设立在老人家中,并评估老人身体情况对其居住的房屋进行适老化改造,安装智华为发狠麒麟980手机一夜降至2600多!众所周知,在手机行业,厂商之间的互怼其实挺普遍。不过,像今年的小米一样,疯狂嘲讽友商的,还是很少见的。比如,在此前的发布会上,小米老总雷军就狂喷华为的荣耀V20,甚至调侃它是PPT国内导航三巨头,如今仅剩高德百度,曾经的行业老大悄然倒下随着科技的日益发展,也改变了我们的生活,各种创新产品层出不穷,给人们的生活带来了非常多的便利。就拿出行方面来说,除了高铁地铁共享单车网约车这些硬性出行方式之外,还有一种软性出行工具小米众筹上架指纹U型锁0。5秒解锁抗14吨液压剪4月9日,小米众筹上架了一款AreoX智能指纹U型锁,支持生物指纹识别,0。5秒快速开锁,众筹价199元(短款22。48cm)219元(长款30cm),预计5月23日开始发货。Ar曝知乎正进行新一轮裁员强制转岗,没补偿,三天不到按旷工辞退4月10日消息,知名微博大V首席内幕官发布微博文章截图。截图文章显示,进入到今年3月份后,知乎业务线全部被砍,强制转岗技术线,拒不配合的员工,如果三天不报道将会以旷工名义辞退。该文