生成密码和解密密码的小工具。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
11 KiB

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-07-08
*/
public class Password {
private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj0yc/l+39O1XukrG1cA4rmJEDlmfdUZHVWFrFkYA3XvZI9FQIYjx/irVurCtXsgn88xWlvEMAlKQVdU5EDvv5qS+9X83LV6tyShFQ4hVa+s1n+eHhWj3PTTTsELN7SEmaCdzFNAcfXYE+c51mvWSioOktORZ4l9Sh3sQ+b/Gir70hJk+ARI2pE2xmEZQCC1vks8rSaay/LuGE+PBkuK42qbcfWkBhvXb8GqnW2+3A61hFa8VSdZmEq5qqDvCUSBxjVhATgAO57qQof3v13lyn8zk+Fg/KYeT1iuxgpVqYjLARyr2f1hZBiiZT5yNtwVVk3+4uP2AyIh+oNAOujNSawIDAQAB";
private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCPTJz+X7f07Ve6SsbVwDiuYkQOWZ91RkdVYWsWRgDde9kj0VAhiPH+KtW6sK1eyCfzzFaW8QwCUpBV1TkQO+/mpL71fzctXq3JKEVDiFVr6zWf54eFaPc9NNOwQs3tISZoJ3MU0Bx9dgT5znWa9ZKKg6S05FniX1KHexD5v8aKvvSEmT4BEjakTbGYRlAILW+SzytJprL8u4YT48GS4rjaptx9aQGG9dvwaqdbb7cDrWEVrxVJ1mYSrmqoO8JRIHGNWEBOAA7nupCh/e/XeXKfzOT4WD8ph5PWK7GClWpiMsBHKvZ/WFkGKJlPnI23BVWTf7i4/YDIiH6g0A66M1JrAgMBAAECggEAJ8Xt9TSADH0r0ksa8Q0PLmeb2BfMCHLfLbWCUYZQiyjq1eQsx4IJGLCu7chH9ny7ihF3HyH8YVClOw2ZbwYTygKD9gO/Ptp+hcylnN7kRrXcBmvu03qU1Ooqr0t7eIuw60u3x1kT70aojuVdAwuSBtwPBR40TH6Em5Hu3kL6SlvU3F9EBDycH1OsonqOaS3z0F7EdFv7NqYKM1VsvhnkfximTE8ikhxdN4vSko9alJii2wM94Hca3NOI6Ug8IkjNr44qj4jVucYzvEw6d0tcWkQRh22dD2617Yeym0tsx+JxMPvMEcOqF3+VRDqb+xFmRrwTh5z0QU96n8r5NcBasQKBgQDv/0ni1SA7EZ3tDesfHSD0dIYk5U6OESzNwWSlmf13Gu7pg71B439O4VIU5OpGrtuA75xHPE6HcwBoEpQjGCYSMerWNhiwPJbXS/CdJVld8ZiIHDu40xCH96EB7y+yG+wueh0HDk/SjwRAcuL58LJnVVje9SSMK3kgeuYrubjkhwKBgQCY2rUMB0KtEisxv/z/YfAfYbCfqp9AGgLYDZjc7cvqczniv7k4AdP0DSOh4eBPe+1whXahhyQ8zkIKZeaYhCV3awXqQJ0D1BhNlMPKnDNzfGfueRnmcji1goiLcuMApqm+33oebPSnv1D6X88M+05S3husJH+lWM51/8eW0zH//QKBgDShY26fFmZdwqhNuRYlqShytUg6ETQOiCjHFG9Mic0o1uPWxBZC8ZQ2zW1PliDSD8kCwt7MVtxVV+16xYm8rfynfbxkOJ3Na7bjLG0J18NGTBDtQBuUDbgDkgd+kJMalHzMwrjdZpviSShpCWWOZ1FJ4idi0xT6I6H/0aIdJHLZAoGBAIOk4QZx/lfGbRMU0ZU1STQN06s/rJXtkQN4em3UE6phALqr+p4k3OG0qzqRqblq9yzQlUI6fNgtn60K5BX4wbfeoaKFcXVJpoCyngmSi7FrtKsq+0aAmxygRm8rTBxUbZ8pIyivF+qdF+X6u/znNyahid2xNYo3OOFhoAji7Y4VAoGBAOXoMHEE1rQsRQEr0p7BFVGTsSwfFCzbiACA5BmQ/fMas2z4lc44MZYqsVHAqqRqbonF+pK2c+6RHqhVpCPC6NTTlqispcP5OTTW2mSj3JFiyTWxkep3m8JiSrJX/uLQcGJHFomPTznHmYLinNlQXm6Z19zkUFIWxvP/QY5SIzKX";
private static final String PUBLIC_KEY_MARK = "public";
private static final String PRIVATE_KEY_MARK = "private";
private static final Pattern PUBLIC_PATTERN = Pattern.compile("-----BEGIN PUBLIC KEY-----([\\s\\S]*?)-----END PUBLIC KEY-----");
private static final Pattern PRIVATE_PATTERN = Pattern.compile("-----BEGIN PRIVATE KEY-----([\\s\\S]*?)-----END PRIVATE KEY-----");
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
private static final int FRAGMENT_LENGTH = 245;
private static final int FRAGMENT_LENGTH_DECRYPT = 256;
private String secretKeyText;
public Password() {
this("");
}
public Password(String secretKeyText) {
this.secretKeyText = secretKeyText;
}
public String getPublicKey() {
return getKey(PUBLIC_KEY_MARK, PUBLIC_KEY);
}
public String getPrivateKey() {
return getKey(PRIVATE_KEY_MARK, PRIVATE_KEY);
}
public void setSecretKeyText(String secretKeyText) {
this.secretKeyText = secretKeyText;
}
private String getKey(String type, String defaultValue) {
Map<String, String> map = getKeyPair();
if (map == null) {
return defaultValue;
}
String value = map.get(type);
if (value == null) {
return defaultValue;
}
return value;
}
private Map<String, String> getKeyPair() {
if (secretKeyText == null || "".equals(secretKeyText)) {
return null;
}
HashMap<String, String> map = new HashMap<>();
map.put(PUBLIC_KEY_MARK, findMatchedText(secretKeyText, PUBLIC_PATTERN));
map.put(PRIVATE_KEY_MARK, findMatchedText(secretKeyText, PRIVATE_PATTERN));
return map;
}
private String findMatchedText(String text, Pattern pattern) {
Matcher m = pattern.matcher(text);
if (m.find()) {
return m.group(1).trim();
}
return "";
}
/**
* RSA加密
*/
public String encrypt(String plainText) {
return encrypt(plainText, string2PublicKey(getPublicKey()));
}
/**
* RSA加密
*
* @param plainText 要加密的文本内容
* @param publicKey 用于加密的公钥
* @return 加密后的内容
*/
public String encrypt(String plainText, Key publicKey) {
if (plainText == null || "".equals(plainText)) {
return plainText;
}
try {
byte[] publicEncrypt = encrypt(plainText.getBytes("utf-8"), publicKey);
return byte2Base64(publicEncrypt);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* RSA加密
*
* @param plainTextData 要加密的内容
* @param publicKey 用于加密的公钥
* @return 加密后的内容
*/
private byte[] encrypt(byte[] plainTextData, Key publicKey) {
if (isEmpty(plainTextData)) {
return plainTextData;
}
try {
Cipher c1 = Cipher.getInstance("RSA");
c1.init(Cipher.ENCRYPT_MODE, publicKey);
return dealEncryptFragment(plainTextData, c1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String decrypt(String cipherText) {
return decrypt(cipherText, string2PrivateKey(getPrivateKey()));
}
/**
* RSA解密
*
* @param cipherText 密文数据
* @return 解密后的内容
*/
public String decrypt(String cipherText, Key privateKey) {
if (cipherText == null || "".equals(cipherText)) {
return cipherText;
}
byte[] bytes = null;
try {
bytes = decrypt(base642Byte(cipherText), privateKey);
} catch (Exception e) {
e.printStackTrace();
}
if (bytes == null) {
return null;
}
try {
return new String(bytes, "utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* RSA解密
*
* @param cipherData 密文数据
* @param privateKey 用于解密的私钥
* @return 解密后的内容
*/
private byte[] decrypt(byte[] cipherData, Key privateKey) {
try {
Cipher c1 = Cipher.getInstance("RSA");
c1.init(Cipher.DECRYPT_MODE, privateKey);
return dealDecryptFragment(cipherData, c1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private PublicKey string2PublicKey(String pubStr) {
try {
byte[] keyBytes = base642Byte(pubStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private PrivateKey string2PrivateKey(String priStr) {
try {
byte[] keyBytes = base642Byte(priStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private byte[] base642Byte(String base64Key) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
return decoder.decodeBuffer(base64Key);
}
private String byte2Base64(byte[] bytes) {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(bytes);
}
private byte[] dealEncryptFragment(byte[] data, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException {
byte[] result = new byte[]{};
int i;
for (i = 0; i < data.length; i += FRAGMENT_LENGTH) {
byte[] fragment = subarray(data, i, i + FRAGMENT_LENGTH);
byte[] update = cipher.doFinal(fragment);
result = addAll(result, update);
}
return result;
}
private byte[] dealDecryptFragment(byte[] data, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException {
byte[] result = new byte[]{};
int i;
for (i = 0; i < data.length; i += FRAGMENT_LENGTH_DECRYPT) {
byte[] fragment = subarray(data, i, i + FRAGMENT_LENGTH_DECRYPT);
byte[] update = cipher.doFinal(fragment);
result = addAll(result, update);
}
return result;
}
public static byte[] subarray(final byte[] array, int startIndexInclusive, int endIndexExclusive) {
if (array == null) {
return null;
}
if (startIndexInclusive < 0) {
startIndexInclusive = 0;
}
if (endIndexExclusive > array.length) {
endIndexExclusive = array.length;
}
final int newSize = endIndexExclusive - startIndexInclusive;
if (newSize <= 0) {
return EMPTY_BYTE_ARRAY;
}
final byte[] subarray = new byte[newSize];
System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
return subarray;
}
public static byte[] addAll(final byte[] array1, final byte... array2) {
if (array1 == null) {
return clone(array2);
} else if (array2 == null) {
return clone(array1);
}
final byte[] joinedArray = new byte[array1.length + array2.length];
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
return joinedArray;
}
public static byte[] clone(final byte[] array) {
if (array == null) {
return null;
}
return array.clone();
}
public static boolean isEmpty(final byte[] array) {
return getLength(array) == 0;
}
public static int getLength(final Object array) {
if (array == null) {
return 0;
}
return Array.getLength(array);
}
}