ECC,AES,SHA256加密技术

ECC加密我查了一些资料显示在jdk中尚未实现完整加密方案,需要加入jar包,使用BC的解决方案,引用的maven仓库jar包如下:

<dependency>
          <groupId>org.bouncycastle</groupId>
          <artifactId>bcprov-jdk15on</artifactId>
          <version>1.60</version>
 </dependency>

ECCUtil加密工具类代码如下:

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.interfaces.ECPublicKey;

public class ECCUtil {

  static {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
  }

  /**
   * 生成秘钥对
   * 
   * @return
   * @throws Exception
   */
  public static KeyPair getKeyPair() throws Exception {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
    keyPairGenerator.initialize(256, new SecureRandom());
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    return keyPair;
  }

  /**
   * 取得私钥
   *
   * @param keyMap
   * @return
   * @throws Exception
   */
  public static String getPrivateKey(KeyPair keyPair) throws Exception {
    ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
    return Base64Util.encryptBASE64(privateKey.getEncoded());
  }

  /**
   * 取得公钥
   *
   * @param keyMap
   * @return
   * @throws Exception
   */
  public static String getPublicKey(KeyPair keyPair) throws Exception {
    ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
    return Base64Util.encryptBASE64(publicKey.getEncoded());
  }

  /**
   * 将Base64编码后的公钥转换成PublicKey对象
   * 
   * @param pubStr
   * @return
   * @throws Exception
   */
  public static ECPublicKey string2PublicKey(String pubStr) throws Exception {
    byte[] keyBytes = Base64Util.decryptBASE64(pubStr);
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
    ECPublicKey publicKey = (ECPublicKey) keyFactory.generatePublic(keySpec);
    return publicKey;
  }

  /**
   * 将Base64编码后的私钥转换成PrivateKey对象
   * 
   * @param priStr
   * @return
   * @throws Exception
   */
  public static ECPrivateKey string2PrivateKey(String priStr) throws Exception {
    byte[] keyBytes = Base64Util.decryptBASE64(priStr);
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
    ECPrivateKey privateKey = (ECPrivateKey) keyFactory.generatePrivate(keySpec);
    return privateKey;
  }

  /**
   * 公钥加密为byte字节
   * 
   * @param content
   * @param publicKey
   * @return
   * @throws Exception
   */
  public static byte[] publicEncrypt(byte[] content, PublicKey publicKey) throws Exception {
    Cipher cipher = Cipher.getInstance("ECIES", "BC");
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] bytes = cipher.doFinal(content);
    return bytes;
  }

  /**
   * 公钥加密转为字符串
   * 
   * @param content
   * @param publicKey
   * @return
   * @throws Exception
   */
  public static String publicEncrypt(String content, PublicKey publicKey) throws Exception {
    byte[] contentBytes = Base64Util.stringToByteArray(content);
    return Base64Util.encryptBASE64(publicEncrypt(contentBytes, publicKey));
  }

  /**
   * 私钥解密为byte字节
   */
  public static byte[] privateDecrypt(byte[] content, PrivateKey privateKey) throws Exception {
    Cipher cipher = Cipher.getInstance("ECIES", "BC");
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] bytes = cipher.doFinal(content);
    return bytes;
  }

  /**
   * 私钥解密为字符串
   */
  public static String privateDecrypt(String content, PrivateKey privateKey) throws Exception {
    byte[] contentBytes = Base64Util.decryptBASE64(content);
    return new String(privateDecrypt(contentBytes, privateKey));
  }
  
  /**
   * base64编码公钥加密为字符串
   */
  public static String publicEncrypt(String content, String publicKeyBase64Str) throws Exception {
    PublicKey publicKey = string2PublicKey(publicKeyBase64Str);
    byte[] contentBytes = Base64Util.stringToByteArray(content);
    return Base64Util.encryptBASE64(publicEncrypt(contentBytes, publicKey));
  }
  
  /**
   * base64编码私钥解密为字符串
   */
  public static String privateDecrypt(String content, String privateKeyBase64Str) throws Exception {
    PrivateKey privateKey=string2PrivateKey(privateKeyBase64Str);
    byte[] contentBytes = Base64Util.decryptBASE64(content);
    return new String(privateDecrypt(contentBytes, privateKey));
  }
}

AES加密模式可选择的模式有许多种类,我用的AES/CBC/PKCS5Padding加密模式,此模式需要加入一个向量参数,增加加密强度,也可选择其他模式,不需要向量参数的参数个数不同.

AESUtil加密工具类如下:

import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class AESUtil {
  // 给定的默认密钥
  private static final String ENCRYPTION_KEY = "RwcmlVpg";
  // 使用AES/CBC/PKCS5Padding模式,加入的向量值
  private static final String ENCRYPTION_IV = "4e5Wa71fYoT7MFEX";
  // 加密模式
  private static final String AESTYPE = "AES/CBC/PKCS5Padding";


  /**
   * 生成密钥
   * 
   * @return
   * @throws Exception
   */
  public static String genKeyAES() throws Exception {
    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(256);
    SecretKey key = keyGen.generateKey();
    String base64Str = Base64Util.encryptBASE64(key.getEncoded());
    return base64Str;
  }

  /**
   * 使用默认给定密钥加密
   * 
   * @param src
   * @return
   */
  public static String encrypt(String src) {
    try {
      Cipher cipher = Cipher.getInstance(AESTYPE);
      cipher.init(Cipher.ENCRYPT_MODE, makeKey(), makeIv());
      return Base64Util.encryptBASE64(cipher.doFinal(src.getBytes()));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }


  /**
   * 使用默认给定密钥解密
   * 
   * @param src
   * @return
   */
  public static String decrypt(String src) {
    String decrypted = "";
    try {
      Cipher cipher = Cipher.getInstance(AESTYPE);
      cipher.init(Cipher.DECRYPT_MODE, makeKey(), makeIv());
      decrypted = new String(cipher.doFinal(Base64Util.decryptBASE64(src)));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return decrypted;
  }

  /**
   * 使用生成的密钥加密
   * 
   * @param src
   * @param key
   * @return
   */
  public static String encrypt(String src, SecretKey key) {
    try {
      Cipher cipher = Cipher.getInstance(AESTYPE);
      cipher.init(Cipher.ENCRYPT_MODE, key, makeIv());
      return Base64Util.encryptBASE64(cipher.doFinal(src.getBytes()));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  
  /**
   * 使用生成的base64密钥加密
   * 
   * @param src
   * @param key
   * @return
   */
  public static String encrypt(String src, String keybase64Str) {
    try {
      SecretKey key=loadKeyAES(keybase64Str);
      Cipher cipher = Cipher.getInstance(AESTYPE);
      cipher.init(Cipher.ENCRYPT_MODE, key, makeIv());
      return Base64Util.encryptBASE64(cipher.doFinal(src.getBytes()));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 使用生成的密钥解密
   * 
   * @param src
   * @param key
   * @return
   */
  public static String decrypt(String src, SecretKey key) {
    String decrypted = "";
    try {
      Cipher cipher = Cipher.getInstance(AESTYPE);
      cipher.init(Cipher.DECRYPT_MODE, key, makeIv());
      decrypted = new String(cipher.doFinal(Base64Util.decryptBASE64(src)));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return decrypted;
  }
  
  /**
   * 使用生成的base64密钥解密
   * 
   * @param src
   * @param key
   * @return
   */
  public static String decrypt(String src, String keybase64Str) {
    String decrypted = "";
    try {
      SecretKey key=loadKeyAES(keybase64Str);
      Cipher cipher = Cipher.getInstance(AESTYPE);
      cipher.init(Cipher.DECRYPT_MODE, key, makeIv());
      decrypted = new String(cipher.doFinal(Base64Util.decryptBASE64(src)));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return decrypted;
  }

  static AlgorithmParameterSpec makeIv() {
    try {
      return new IvParameterSpec(ENCRYPTION_IV.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return null;
  }

  static Key makeKey() {
    try {
      MessageDigest md = MessageDigest.getInstance("SHA-256");
      byte[] key = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
      return new SecretKeySpec(key, "AES");
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 将Base64编码后的AES秘钥转换成SecretKey对象
   * 
   * @param base64Key
   * @return
   * @throws Exception
   */
  public static SecretKey loadKeyAES(String base64Key) throws Exception {
    byte[] bytes = Base64Util.decryptBASE64(base64Key);
    SecretKeySpec key = new SecretKeySpec(bytes, "AES");
    return key;
  }

  /**
   * 使用传入的参数密码生成密钥加密
   * 
   * @param content
   * @param password
   * @return
   */
  public static String encryptByPassword(String content, String password) {
    try {
      // "AES":请求的密钥算法的标准名称
      KeyGenerator kgen = KeyGenerator.getInstance("AES");
      // 256:密钥生成参数;securerandom:密钥生成器的随机源
      SecureRandom securerandom = SecureRandom.getInstance("SHA1PRNG");
      securerandom.setSeed(tohash256Deal(password));
      kgen.init(256, securerandom);
      // 生成秘密(对称)密钥
      SecretKey secretKey = kgen.generateKey();
      // 返回基本编码格式的密钥
      byte[] enCodeFormat = secretKey.getEncoded();
      // 根据给定的字节数组构造一个密钥。enCodeFormat:密钥内容;"AES":与给定的密钥内容相关联的密钥算法的名称
      SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
      // 将提供程序添加到下一个可用位置
      Security.addProvider(new BouncyCastleProvider());
      // 创建一个实现指定转换的 Cipher对象,该转换由指定的提供程序提供。
      // "AES/ECB/PKCS7Padding":转换的名称;"BC":提供程序的名称
      Cipher cipher = Cipher.getInstance(AESTYPE);

      cipher.init(Cipher.ENCRYPT_MODE, key, makeIv());
      return Base64Util.encryptBASE64(cipher.doFinal(content.getBytes()));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 使用传入的参数密码生成密钥解密
   * 
   * @param content
   * @param password
   * @return
   */
  public static String decryptByPassword(String content, String password) {
    try {
      KeyGenerator kgen = KeyGenerator.getInstance("AES");
      SecureRandom securerandom = SecureRandom.getInstance("SHA1PRNG");
      securerandom.setSeed(tohash256Deal(password));
      kgen.init(256, securerandom);
      SecretKey secretKey = kgen.generateKey();
      byte[] enCodeFormat = secretKey.getEncoded();
      SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
      Security.addProvider(new BouncyCastleProvider());
      Cipher cipher = Cipher.getInstance(AESTYPE);

      cipher.init(Cipher.DECRYPT_MODE, key, makeIv());
      return new String(cipher.doFinal(Base64Util.decryptBASE64(content)));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  private static byte[] tohash256Deal(String datastr) {
    try {
      MessageDigest digester = MessageDigest.getInstance("SHA-256");
      digester.update(datastr.getBytes());
      byte[] hex = digester.digest();
      return hex;
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException(e.getMessage());
    }
  }
}

SHA256Util加密工具类如下:

import java.security.MessageDigest;

public class SHA256Util {
  private static final String salt = "gfdsh@59*76%^fjkdsa24";

  /**
   * 不加盐加密
   * 
   * @param origin
   * @param charsetname
   * @return
   */
  public static String string2SHA256(String origin, String charsetname) {
    String resultString = null;
    try {
      resultString = new String(origin);
      MessageDigest md = MessageDigest.getInstance("SHA-256");
      if (charsetname == null || "".equals(charsetname))
        resultString = byte2Hex(md.digest(resultString.getBytes()));
      else
        resultString = byte2Hex(md.digest(resultString.getBytes(charsetname)));
    } catch (Exception exception) {
    }
    return resultString;
  }

  /**
   * 加盐加密
   * 
   * @param origin
   * @return
   */
  public static String encryptSHA256(String origin) {
    origin = origin + salt;
    return string2SHA256(origin, "utf-8");
  }

  /**
   * 将byte转为16进制
   * 
   * @param bytes
   * @return
   */
  private static String byte2Hex(byte[] bytes) {
    StringBuffer stringBuffer = new StringBuffer();
    String temp = null;
    for (int i = 0; i < bytes.length; i++) {
      temp = Integer.toHexString(bytes[i] & 0xFF);
      if (temp.length() == 1) {
        // 1得到一位的进行补0操作
        stringBuffer.append("0");
      }
      stringBuffer.append(temp);
    }
    return stringBuffer.toString();
  }
}
 

上述工具类使用了base64编码,编码工具类如下:

Base64Util编码工具类:

import java.io.UnsupportedEncodingException;
import java.util.Base64;

public class Base64Util {
  public static byte[] decryptBASE64(String data) {
    return Base64.getDecoder().decode(data);// Base64..decodeBase64(data);
  }

  public static String encryptBASE64(byte[] data) {
    return Base64.getEncoder().encodeToString(data);// new String(Base64.encodeBase64(data));
  }

  public static String byteArrayToString(byte[] byteArray) {
    try {
      return new String(byteArray, "UTF8");
    } catch (final UnsupportedEncodingException e) {
      return new String(byteArray);
    }
  }

  public static byte[] stringToByteArray(String input) {
    try {
      return input.getBytes("UTF-8");
    } catch (UnsupportedEncodingException fallbackToDefault) {
      return input.getBytes();
    }
  }
}

jdk对加密强度有一定限制,如果加密工具类报错,可能与jdk加密强度有关,可以下载jdk的加密扩展包,过程如下:

去jdk官网下载加密扩展包,如果是jdk8,

下载jce_policy-8.zip扩展包

下载下来以后,需要将local_policy.jar 和 US_export_policy.jar替换掉***\Java\jdk1.8.0_91\jre\lib\security下面的相同的两个jar包。 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值