|
@@ -0,0 +1,212 @@
|
|
|
|
|
+package cn.chinaunicom.omniFlowNetCompute.service;
|
|
|
|
|
+
|
|
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
|
|
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
|
|
+import org.bouncycastle.openssl.PEMDecryptorProvider;
|
|
|
|
|
+import org.bouncycastle.openssl.PEMEncryptedKeyPair;
|
|
|
|
|
+import org.bouncycastle.openssl.PEMKeyPair;
|
|
|
|
|
+import org.bouncycastle.openssl.PEMParser;
|
|
|
|
|
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
|
|
|
|
+import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
|
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
+import org.springframework.core.io.ClassPathResource;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import javax.crypto.BadPaddingException;
|
|
|
|
|
+import javax.crypto.Cipher;
|
|
|
|
|
+import javax.crypto.IllegalBlockSizeException;
|
|
|
|
|
+import javax.crypto.NoSuchPaddingException;
|
|
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
+import java.io.InputStreamReader;
|
|
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
|
|
+import java.security.*;
|
|
|
|
|
+import java.security.spec.InvalidKeySpecException;
|
|
|
|
|
+import java.security.spec.KeySpec;
|
|
|
|
|
+import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
|
|
+import java.security.spec.X509EncodedKeySpec;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * RSA加密相关服务
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author Kitty
|
|
|
|
|
+ * @date 2018-04-13
|
|
|
|
|
+ */
|
|
|
|
|
+@Service
|
|
|
|
|
+public class RsaService {
|
|
|
|
|
+
|
|
|
|
|
+ private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(RsaService.class);
|
|
|
|
|
+
|
|
|
|
|
+ private PrivateKey privateKey = null;
|
|
|
|
|
+ private PublicKey publicKey = null;
|
|
|
|
|
+ private static final String PEM_FILE_NAME = "private_key.pem";
|
|
|
|
|
+ private static final char[] PEM_FILE_PASSWORD = "123456".toCharArray();
|
|
|
|
|
+
|
|
|
|
|
+ private PublicKey getPublicKey() {
|
|
|
|
|
+ if (null == this.publicKey) {
|
|
|
|
|
+ this.initKey();
|
|
|
|
|
+ }
|
|
|
|
|
+ return this.publicKey;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private PrivateKey getPrivateKey() {
|
|
|
|
|
+ if (null == this.privateKey) {
|
|
|
|
|
+ this.initKey();
|
|
|
|
|
+ }
|
|
|
|
|
+ return this.privateKey;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void initKey() {
|
|
|
|
|
+ KeyPair keyPair = null;
|
|
|
|
|
+ PEMParser pemParser = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ Security.addProvider(new BouncyCastleProvider());
|
|
|
|
|
+ // private key file in PEM format
|
|
|
|
|
+ pemParser = new PEMParser(new InputStreamReader(new ClassPathResource(PEM_FILE_NAME).getInputStream(), "UTF-8"));
|
|
|
|
|
+ Object object = pemParser.readObject();
|
|
|
|
|
+ PEMDecryptorProvider decryptorProvider = new JcePEMDecryptorProviderBuilder().build(PEM_FILE_PASSWORD);
|
|
|
|
|
+ JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
|
|
|
|
|
+ if (object instanceof PEMEncryptedKeyPair) {
|
|
|
|
|
+ System.out.println("Encrypted key - we will use provided password");
|
|
|
|
|
+ keyPair = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decryptorProvider));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ System.out.println("Unencrypted key - no password needed");
|
|
|
|
|
+ keyPair = converter.getKeyPair((PEMKeyPair) object);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
|
+ LOGGER.error(ex.getMessage(), ex);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ if (null != pemParser) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ pemParser.close();
|
|
|
|
|
+ } catch (IOException ex) {
|
|
|
|
|
+ LOGGER.error(ex.getMessage(), ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (null != keyPair) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
|
|
+ KeySpec publicKeySpec = new X509EncodedKeySpec(keyPair.getPublic().getEncoded());
|
|
|
|
|
+ this.publicKey = keyFactory.generatePublic(publicKeySpec);
|
|
|
|
|
+ KeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyPair.getPrivate().getEncoded());
|
|
|
|
|
+ this.privateKey = keyFactory.generatePrivate(privateKeySpec);
|
|
|
|
|
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
|
|
|
|
|
+ LOGGER.error(ex.getMessage(), ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 进行签名
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public String sign(byte[] data) {
|
|
|
|
|
+ String result = null;
|
|
|
|
|
+ if (null != this.getPrivateKey()) {
|
|
|
|
|
+ Signature signature;
|
|
|
|
|
+ try {
|
|
|
|
|
+ signature = Signature.getInstance("MD5withRSA");
|
|
|
|
|
+ signature.initSign(this.getPrivateKey());
|
|
|
|
|
+ signature.update(data);
|
|
|
|
|
+ result = Base64.encodeBase64String(signature.sign());
|
|
|
|
|
+ } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException ex) {
|
|
|
|
|
+ LOGGER.error(ex.getMessage(), ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private byte[] doFinal(Cipher cipher, byte[] source, int length) throws BadPaddingException, IllegalBlockSizeException, IOException {
|
|
|
|
|
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
|
|
+ int offset = 0;
|
|
|
|
|
+ while (offset < source.length) {
|
|
|
|
|
+ if (source.length < offset + length) {
|
|
|
|
|
+ length = source.length - offset;
|
|
|
|
|
+ }
|
|
|
|
|
+ outputStream.write(cipher.doFinal(source, offset, length));
|
|
|
|
|
+ offset += length;
|
|
|
|
|
+ }
|
|
|
|
|
+ return outputStream.toByteArray();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 数据加密
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public String encrypt(String data) {
|
|
|
|
|
+ String result = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ result = this.encrypt(data.getBytes("UTF-8"));
|
|
|
|
|
+ } catch (UnsupportedEncodingException ex) {
|
|
|
|
|
+ LOGGER.error(ex.getMessage(), ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 数据加密
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public String encrypt(byte[] data) {
|
|
|
|
|
+ String result = null;
|
|
|
|
|
+ if (null != this.getPublicKey()) {
|
|
|
|
|
+ Cipher cipher;
|
|
|
|
|
+ try {
|
|
|
|
|
+ cipher = Cipher.getInstance("RSA");
|
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, this.getPublicKey());
|
|
|
|
|
+ result = Base64.encodeBase64String(this.doFinal(cipher, data, 117));
|
|
|
|
|
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | IOException ex) {
|
|
|
|
|
+ LOGGER.error(ex.getMessage(), ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 数据解密
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public String decrypt(String data) {
|
|
|
|
|
+ return this.decrypt(Base64.decodeBase64(data));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 数据解密
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public String decrypt(byte[] data) {
|
|
|
|
|
+ String result = null;
|
|
|
|
|
+ if (null != this.getPrivateKey()) {
|
|
|
|
|
+ Cipher cipher;
|
|
|
|
|
+ try {
|
|
|
|
|
+ cipher = Cipher.getInstance("RSA");
|
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, this.getPrivateKey());
|
|
|
|
|
+ result = new String(this.doFinal(cipher, data, 128), "UTF-8");
|
|
|
|
|
+ } catch (BadPaddingException | IllegalBlockSizeException | IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException ex) {
|
|
|
|
|
+ LOGGER.error(ex.getMessage(), ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
|
+ RsaService rsa = new RsaService();
|
|
|
|
|
+ String encrypt = rsa.encrypt("test1");
|
|
|
|
|
+ System.out.println(encrypt);
|
|
|
|
|
+
|
|
|
|
|
+ String password = rsa.decrypt("KqPTcY4x7/jHq1otgdFiGLJGZDYH1719usXH02m5sP8E5AMEfryG3J7Lx9VVIbezgqQeGuyQzJaTCYMQD7cX8HxMmXbzElwij2hCX8GswVTeBagcVynwnckoL1ge4KBm5VfiUAnKbmiHqXHOSclneUqk3bN/Mdmfm0+haqPf2KY=");
|
|
|
|
|
+ System.out.println(password);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|