일단 암호화로직 구현
This commit is contained in:
parent
0128f2b843
commit
a623db316c
37
build.gradle
37
build.gradle
|
@ -1,6 +1,21 @@
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
maven { url 'http://repo.spring.io/snapshot' }
|
||||||
|
maven { url 'http://repo.spring.io/milestone' }
|
||||||
|
maven { url 'http://repo.spring.io/plugins-release' }
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'org.springframework.build.gradle:propdeps-plugin:0.0.7'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mainClassName = 'Main'
|
||||||
|
//mainClassName = 'SimpleObfuscator'
|
||||||
|
//mainClassName = 'Crypt'
|
||||||
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -9,8 +24,24 @@ repositories {
|
||||||
maven { url 'http://repo.spring.io/snapshot' }
|
maven { url 'http://repo.spring.io/snapshot' }
|
||||||
maven { url 'http://repo.spring.io/milestone' }
|
maven { url 'http://repo.spring.io/milestone' }
|
||||||
maven { url 'http://repo.spring.io/plugins-release' }
|
maven { url 'http://repo.spring.io/plugins-release' }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
apply plugin: 'propdeps'
|
||||||
|
apply plugin: 'propdeps-maven'
|
||||||
|
apply plugin: 'propdeps-idea'
|
||||||
|
apply plugin: 'propdeps-eclipse'
|
||||||
|
dependencies {
|
||||||
|
compile 'org.bouncycastle:bcprov-jdk15on:1.54'
|
||||||
|
provided 'org.projectlombok:lombok:1.16.10'
|
||||||
|
|
||||||
|
// commons family
|
||||||
|
compile 'org.apache.commons:commons-lang3:3.4'
|
||||||
|
compile 'commons-codec:commons-codec:1.10'
|
||||||
|
compile 'commons-io:commons-io:2.5'
|
||||||
|
compile 'commons-fileupload:commons-fileupload:1.3.1'
|
||||||
|
compile 'com.google.guava:guava:19.0'
|
||||||
|
compile "com.fasterxml.uuid:java-uuid-generator:3.1.4"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
dependencies{
|
|
||||||
compile group: 'org.bouncycastle:bcprov-jdk15on:1.54'
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
#Mon Aug 01 04:55:26 KST 2016
|
#Mon Oct 10 00:54:38 KST 2016
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base58 is a way to encode Bitcoin addresses (or arbitrary data) as alphanumeric strings.
|
||||||
|
* <p>
|
||||||
|
* Note that this is not the same base58 as used by Flickr, which you may find referenced around the Internet.
|
||||||
|
* <p>
|
||||||
|
* adds support for testing the prefix and suffix bytes commonly found in addresses.
|
||||||
|
* <p>
|
||||||
|
* Satoshi explains: why base-58 instead of standard base-64 encoding?
|
||||||
|
* <ul>
|
||||||
|
* <li>Don't want 0OIl characters that look the same in some fonts and
|
||||||
|
* could be used to create visually identical looking account numbers.</li>
|
||||||
|
* <li>A string with non-alphanumeric characters is not as easily accepted as an account number.</li>
|
||||||
|
* <li>E-mail usually won't line-break if there's no punctuation to break at.</li>
|
||||||
|
* <li>Doubleclicking selects the whole number as one word if it's all alphanumeric.</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* However, note that the encoding/decoding runs in O(n²) time, so it is not useful for large data.
|
||||||
|
* <p>
|
||||||
|
* The basic idea of the encoding is to treat the data bytes as a large number represented using
|
||||||
|
* base-256 digits, convert the number to be represented using base-58 digits, preserve the exact
|
||||||
|
* number of leading zeros (which are otherwise lost during the mathematical operations on the
|
||||||
|
* numbers), and finally represent the resulting base-58 digits as alphanumeric ASCII characters.
|
||||||
|
*/
|
||||||
|
public class Base58 {
|
||||||
|
private static final char[] ALPHABET = ("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz").toCharArray();
|
||||||
|
private static final char ENCODED_ZERO = ALPHABET[0];
|
||||||
|
private static final int[] INDEXES = new int[128];
|
||||||
|
|
||||||
|
static {
|
||||||
|
Arrays.fill(INDEXES, -1);
|
||||||
|
for (int i = 0; i < ALPHABET.length; i++) {
|
||||||
|
INDEXES[ALPHABET[i]] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encodeChecked(byte[] input) {
|
||||||
|
byte[] data = Arrays.copyOfRange(input, 0, input.length);
|
||||||
|
byte[] checksum = ByteUtil.toBytes(Hashing.sha256().hashBytes(data).hashCode());
|
||||||
|
return encode(ArrayUtils.addAll(data,checksum));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Encodes the given bytes as a base58 string (no checksum is appended).
|
||||||
|
*
|
||||||
|
* @param input the bytes to encode
|
||||||
|
* @return the base58-encoded string
|
||||||
|
*/
|
||||||
|
public static String encode(byte[] input) {
|
||||||
|
if (input.length == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Count leading zeros.
|
||||||
|
int zeros = 0;
|
||||||
|
while (zeros < input.length && input[zeros] == 0) {
|
||||||
|
++zeros;
|
||||||
|
}
|
||||||
|
// Convert base-256 digits to base-58 digits (plus conversion to ASCII characters)
|
||||||
|
input = Arrays.copyOf(input, input.length); // since we modify it in-place
|
||||||
|
char[] encoded = new char[input.length * 2]; // upper bound
|
||||||
|
int outputStart = encoded.length;
|
||||||
|
for (int inputStart = zeros; inputStart < input.length; ) {
|
||||||
|
encoded[--outputStart] = ALPHABET[divmod(input, inputStart, 256, 58)];
|
||||||
|
if (input[inputStart] == 0) {
|
||||||
|
++inputStart; // optimization - skip leading zeros
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Preserve exactly as many leading encoded zeros in output as there were leading zeros in input.
|
||||||
|
while (outputStart < encoded.length && encoded[outputStart] == ENCODED_ZERO) {
|
||||||
|
++outputStart;
|
||||||
|
}
|
||||||
|
while (--zeros >= 0) {
|
||||||
|
encoded[--outputStart] = ENCODED_ZERO;
|
||||||
|
}
|
||||||
|
// Return encoded string (including encoded leading zeros).
|
||||||
|
return new String(encoded, outputStart, encoded.length - outputStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the given base58 string into the original data bytes.
|
||||||
|
*
|
||||||
|
* @param input the base58-encoded string to decode
|
||||||
|
* @return the decoded data bytes
|
||||||
|
* @throws IllegalArgumentException if the given string is not a valid base58 string
|
||||||
|
*/
|
||||||
|
public static byte[] decode(String input) throws IllegalArgumentException {
|
||||||
|
if (input.length() == 0) {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
// Convert the base58-encoded ASCII chars to a base58 byte sequence (base58 digits).
|
||||||
|
byte[] input58 = new byte[input.length()];
|
||||||
|
for (int i = 0; i < input.length(); ++i) {
|
||||||
|
char c = input.charAt(i);
|
||||||
|
int digit = c < 128 ? INDEXES[c] : -1;
|
||||||
|
if (digit < 0) {
|
||||||
|
System.out.printf("Illegal character %d at position %d\n",c,i);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
input58[i] = (byte) digit;
|
||||||
|
}
|
||||||
|
// Count leading zeros.
|
||||||
|
int zeros = 0;
|
||||||
|
while (zeros < input58.length && input58[zeros] == 0) {
|
||||||
|
++zeros;
|
||||||
|
}
|
||||||
|
// Convert base-58 digits to base-256 digits.
|
||||||
|
byte[] decoded = new byte[input.length()];
|
||||||
|
int outputStart = decoded.length;
|
||||||
|
for (int inputStart = zeros; inputStart < input58.length; ) {
|
||||||
|
decoded[--outputStart] = divmod(input58, inputStart, 58, 256);
|
||||||
|
if (input58[inputStart] == 0) {
|
||||||
|
++inputStart; // optimization - skip leading zeros
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ignore extra leading zeroes that were added during the calculation.
|
||||||
|
while (outputStart < decoded.length && decoded[outputStart] == 0) {
|
||||||
|
++outputStart;
|
||||||
|
}
|
||||||
|
// Return decoded data (including original number of leading zeros).
|
||||||
|
return Arrays.copyOfRange(decoded, outputStart - zeros, decoded.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BigInteger decodeToBigInteger(String input) throws IllegalArgumentException {
|
||||||
|
return new BigInteger(1, decode(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the given base58 string into the original data bytes, using the checksum in the
|
||||||
|
* last 4 bytes of the decoded data to verify that the rest are correct. The checksum is
|
||||||
|
* removed from the returned data.
|
||||||
|
*
|
||||||
|
* @param input the base58-encoded string to decode (which should include the checksum)
|
||||||
|
* @throws IllegalArgumentException if the input is not base 58 or the checksum does not validate.
|
||||||
|
*/
|
||||||
|
public static byte[] decodeChecked(String input) throws IllegalArgumentException {
|
||||||
|
byte[] decoded = decode(input);
|
||||||
|
if (decoded.length < 8) {
|
||||||
|
System.out.println("Input too short");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] data = Arrays.copyOfRange(decoded, 0, decoded.length - 4);
|
||||||
|
byte[] checksum = Arrays.copyOfRange(decoded, decoded.length -4, decoded.length);
|
||||||
|
byte[] actualChecksum = ByteUtil.toBytes(Hashing.sha256().hashBytes(data).hashCode());
|
||||||
|
|
||||||
|
if (!Arrays.equals(checksum, actualChecksum)) {
|
||||||
|
System.out.println("Checksum does not validate");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divides a number, represented as an array of bytes each containing a single digit
|
||||||
|
* in the specified base, by the given divisor. The given number is modified in-place
|
||||||
|
* to contain the quotient, and the return value is the remainder.
|
||||||
|
*
|
||||||
|
* @param number the number to divide
|
||||||
|
* @param firstDigit the index within the array of the first non-zero digit
|
||||||
|
* (this is used for optimization by skipping the leading zeros)
|
||||||
|
* @param base the base in which the number's digits are represented (up to 256)
|
||||||
|
* @param divisor the number to divide by (up to 256)
|
||||||
|
* @return the remainder of the division operation
|
||||||
|
*/
|
||||||
|
private static byte divmod(byte[] number, int firstDigit, int base, int divisor) {
|
||||||
|
// this is just long division which accounts for the base of the input digits
|
||||||
|
int remainder = 0;
|
||||||
|
for (int i = firstDigit; i < number.length; i++) {
|
||||||
|
int digit = (int) number[i] & 0xFF;
|
||||||
|
int temp = remainder * base + digit;
|
||||||
|
number[i] = (byte) (temp / divisor);
|
||||||
|
remainder = temp % divisor;
|
||||||
|
}
|
||||||
|
return (byte) remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
|
||||||
|
public class ByteUtil {
|
||||||
|
public static int fromBytesAsInt(byte[] i) {
|
||||||
|
|
||||||
|
return
|
||||||
|
(((int) i[3] & 0xFF) << 24) |
|
||||||
|
(((int) i[2] & 0xFF) << 16) |
|
||||||
|
(((int) i[1] & 0xFF) << 8) |
|
||||||
|
(((int) i[0] & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long fromBytesAsLong(byte[] i) {
|
||||||
|
|
||||||
|
|
||||||
|
return
|
||||||
|
(((long) i[0] & 0xFF) << 56) |
|
||||||
|
(((long) i[1] & 0xFF) << 48) |
|
||||||
|
(((long) i[2] & 0xFF) << 40) |
|
||||||
|
(((long) i[3] & 0xFF) << 32) |
|
||||||
|
(((long) i[4] & 0xFF) << 24) |
|
||||||
|
(((long) i[5] & 0xFF) << 16) |
|
||||||
|
(((long) i[6] & 0xFF) << 8) |
|
||||||
|
(((long) i[7] & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long fromBytesAsLongMost(byte[] i) {
|
||||||
|
|
||||||
|
return
|
||||||
|
(((long) i[0] & 0xFF) << 56) |
|
||||||
|
(((long) i[1] & 0xFF) << 48) |
|
||||||
|
(((long) i[2] & 0xFF) << 40) |
|
||||||
|
(((long) i[3] & 0xFF) << 32) |
|
||||||
|
(((long) i[4] & 0xFF) << 24) |
|
||||||
|
(((long) i[5] & 0xFF) << 16) |
|
||||||
|
(((long) i[6] & 0xFF) << 8) |
|
||||||
|
(((long) i[7] & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long fromBytesAsLongLast(byte[] i) {
|
||||||
|
|
||||||
|
return
|
||||||
|
(((long) i[8] & 0xFF) << 56) |
|
||||||
|
(((long) i[9] & 0xFF) << 48) |
|
||||||
|
(((long) i[10] & 0xFF) << 40) |
|
||||||
|
(((long) i[11] & 0xFF) << 32) |
|
||||||
|
(((long) i[12] & 0xFF) << 24) |
|
||||||
|
(((long) i[13] & 0xFF) << 16) |
|
||||||
|
(((long) i[14] & 0xFF) << 8) |
|
||||||
|
(((long) i[15] & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] toBytes(int i) {
|
||||||
|
byte[] result = new byte[4];
|
||||||
|
|
||||||
|
result[0] = (byte) (i >> 24);
|
||||||
|
result[1] = (byte) (i >> 16);
|
||||||
|
result[2] = (byte) (i >> 8);
|
||||||
|
result[3] = (byte) (i /*>> 0*/);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] toBytes(long i) {
|
||||||
|
byte[] result = new byte[8];
|
||||||
|
|
||||||
|
result[0] = (byte) (i >> 56);
|
||||||
|
result[1] = (byte) (i >> 48);
|
||||||
|
result[2] = (byte) (i >> 40);
|
||||||
|
result[3] = (byte) (i >> 32);
|
||||||
|
result[4] = (byte) (i >> 24);
|
||||||
|
result[5] = (byte) (i >> 16);
|
||||||
|
result[6] = (byte) (i >> 8);
|
||||||
|
result[7] = (byte) (i /*>> 0*/);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] toBytes(long most, long last) {
|
||||||
|
byte[] result = new byte[16];
|
||||||
|
|
||||||
|
result[0] = (byte) (most >> 56);
|
||||||
|
result[1] = (byte) (most >> 48);
|
||||||
|
result[2] = (byte) (most >> 40);
|
||||||
|
result[3] = (byte) (most >> 32);
|
||||||
|
result[4] = (byte) (most >> 24);
|
||||||
|
result[5] = (byte) (most >> 16);
|
||||||
|
result[6] = (byte) (most >> 8);
|
||||||
|
result[7] = (byte) (most /*>> 0*/);
|
||||||
|
result[8] = (byte) (last >> 56);
|
||||||
|
result[9] = (byte) (last >> 48);
|
||||||
|
result[10] = (byte) (last >> 40);
|
||||||
|
result[11] = (byte) (last >> 32);
|
||||||
|
result[12] = (byte) (last >> 24);
|
||||||
|
result[13] = (byte) (last >> 16);
|
||||||
|
result[14] = (byte) (last >> 8);
|
||||||
|
result[15] = (byte) (last /*>> 0*/);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||||
|
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
|
||||||
|
import org.bouncycastle.crypto.params.KeyParameter;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
public class CryptoUtil {
|
||||||
|
|
||||||
|
private static final Charset characterSetUtf8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
private static final Charset characterSetAscii = Charset.forName("US-ASCII");
|
||||||
|
|
||||||
|
public static Cipher cipherFactory(String secretKey, String secretIv, String salt, int mode) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
//PBKDF2WithHmacSHA256
|
||||||
|
final PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
|
||||||
|
gen.init(secretKey.getBytes(characterSetAscii), salt.getBytes(characterSetAscii), 2);
|
||||||
|
final byte[] dk = ((KeyParameter) gen.generateDerivedParameters(256)).getKey();
|
||||||
|
SecretKey secret = new SecretKeySpec(dk, "AES");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
cipher.init(mode, secret, new IvParameterSpec(secretIv.getBytes(characterSetAscii)));
|
||||||
|
return cipher;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("CryptoUtil.cipherFactory - fail to create cipher %s %s\n", e.getMessage(), mode);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] encode(Cipher cipher, byte[] payload) {
|
||||||
|
if (payload == null || cipher == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return cipher.doFinal(payload);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("CryptoUtil.decode - fail to encode %s %s", payload, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decode(Cipher cipher, byte[] encrypted) {
|
||||||
|
if (encrypted== null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return cipher.doFinal(encrypted);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("CryptoUtil.decode - fail to decode {} {}", encrypted, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode64(Cipher cipher, String payload) {
|
||||||
|
if (payload == null || cipher == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] encrypted = cipher.doFinal(payload.getBytes(characterSetUtf8));
|
||||||
|
return String.valueOf(Base64.encode(encrypted));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("CryptoUtil.decode - fail to encode %s %s", payload, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decode64(Cipher cipher, String encryptedSessionInfo) {
|
||||||
|
if (encryptedSessionInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] byteStr = Base64.decode(encryptedSessionInfo);
|
||||||
|
return new String(cipher.doFinal(byteStr), characterSetUtf8);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("CryptoUtil.decode - fail to decode {} {}", encryptedSessionInfo, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode58(Cipher cipher, String payload) {
|
||||||
|
if (payload == null || cipher == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] encrypted = cipher.doFinal(payload.getBytes(characterSetUtf8));
|
||||||
|
return Base58.encodeChecked(encrypted);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("CryptoUtil.decode - fail to encode %s %s", payload, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decode58(Cipher cipher, String encryptedSessionInfo) {
|
||||||
|
if (encryptedSessionInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] byteStr = Base58.decodeChecked(encryptedSessionInfo);
|
||||||
|
if(byteStr==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new String(cipher.doFinal(byteStr), characterSetUtf8);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("CryptoUtil.decode - fail to decode {} {}", encryptedSessionInfo, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* timestamp
|
||||||
|
*
|
||||||
|
* @param encodedSessionInfo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getAccessTokenIfValid(Cipher cipher, String encodedSessionInfo) {
|
||||||
|
if (encodedSessionInfo == null || cipher == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String decodedSessionInfo = decode58(cipher, encodedSessionInfo);
|
||||||
|
StringTokenizer splitted = decodedSessionInfo == null ? null : new StringTokenizer(decodedSessionInfo, ":");
|
||||||
|
|
||||||
|
if (splitted == null || splitted.countTokens() != 2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return decodedSessionInfo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||||
|
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
|
||||||
|
import org.bouncycastle.crypto.params.KeyParameter;
|
||||||
|
|
||||||
|
import javax.crypto.*;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by spi-ca on 10/10/2016.
|
||||||
|
*/
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
|
||||||
|
private static final Charset characterSetUtf8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
private static final Charset characterSetAscii = Charset.forName("US-ASCII");
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
UUID target = UUID.fromString("abd91313-e6d6-45be-9913-13e6d6d5bef2");
|
||||||
|
|
||||||
|
String secretKey = "WHc3zv6ZaWnnBz2XZwvhKWucwXWk3Tzz";
|
||||||
|
String secretIv = "mRzpK5yUsLreMCTg";
|
||||||
|
String salt = "vvgKbpRxzY8zC9LC";
|
||||||
|
|
||||||
|
//PBKDF2WithHmacSHA256
|
||||||
|
final PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
|
||||||
|
gen.init(secretKey.getBytes(characterSetAscii), salt.getBytes(characterSetAscii), 2);
|
||||||
|
final byte[] dk = ((KeyParameter) gen.generateDerivedParameters(256)).getKey();
|
||||||
|
|
||||||
|
SecretKey secret = new SecretKeySpec(dk, "AES");
|
||||||
|
try {
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(secretIv.getBytes(characterSetAscii)));
|
||||||
|
byte[] encrypted = cipher.doFinal(UUIDUtil.UUIDToBytes(target));
|
||||||
|
|
||||||
|
System.out.printf("uuid : %s base58 : %s enc: %s \n",
|
||||||
|
target.toString(),
|
||||||
|
Base58.encode(UUIDUtil.UUIDToBytes(target)),
|
||||||
|
Base58.encode(encrypted)
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (InvalidKeyException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cipher encryptor = CryptoUtil.cipherFactory(secretKey, secretIv, salt, Cipher.ENCRYPT_MODE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,9 +4,7 @@ import org.bouncycastle.crypto.params.KeyParameter;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.SecretKeyFactory;
|
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
@ -38,13 +36,6 @@ public class SimpleEncryptor {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
||||||
// SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
|
||||||
// KeySpec keySpec = new PBEKeySpec(new String(keyValue, characterSetAscii).toCharArray(), salt, 2, 256);
|
|
||||||
// SecretKey tmp = factory.generateSecret(keySpec);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
//PBKDF2WithHmacSHA256
|
//PBKDF2WithHmacSHA256
|
||||||
final PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
|
final PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
|
||||||
gen.init(keyValue, salt, 2);
|
gen.init(keyValue, salt, 2);
|
||||||
|
@ -60,7 +51,6 @@ public class SimpleEncryptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte[] encrypt(byte[] source) {
|
public byte[] encrypt(byte[] source) {
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -81,7 +71,6 @@ public class SimpleEncryptor {
|
||||||
return decryptor.doFinal(source);
|
return decryptor.doFinal(source);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +80,11 @@ public class SimpleEncryptor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return new String(Base64.encode(encryptor.doFinal(source.getBytes(characterSetAscii))));
|
byte[] payload = encrypt(source.getBytes(characterSetAscii));
|
||||||
|
if (payload == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new String(Base64.encode(payload));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
@ -103,10 +96,16 @@ public class SimpleEncryptor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return new String(decryptor.doFinal(Base64.decode(source)), characterSetUtf8);
|
|
||||||
|
byte[] payload = decrypt(Base64.decode(source));
|
||||||
|
if (payload == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new String(payload, characterSetUtf8);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
public class SimpleObfuscator {
|
public class SimpleObfuscator {
|
||||||
|
@ -59,16 +62,18 @@ public class SimpleObfuscator {
|
||||||
// "sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=",
|
// "sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=",
|
||||||
// "sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME="
|
// "sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME="
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
||||||
//dbkeys
|
//dbkeys
|
||||||
byte[][] keys = {
|
byte[][] keys = {
|
||||||
{-45, 38, 70, -101, -53, 80, 47, -11, -103, 19, 60, 72, 95, -86, 105, 121, -68, 58, 106, -100, -72, 56, -44, -43, 35, 100, -35, 40, 125, -93, 58, -120, 96, -56, 50, -18, -113, -50, 62, 27, -76, -36, -99, 36, 112, 62, -6, -39, 117, -56, -74, 68, 82, 35, -50, -109, -66, 11, 69, 124, 11, -36, -9, -1},
|
{-45, 38, 70, -101, -53, 80, 47, -11, -103, 19, 60, 72, 95, -86, 105, 121, -68, 58, 106, -100, -72, 56, -44, -43, 35, 100, -35, 40, 125, -93, 58, -120, 96, -56, 50, -18, -113, -50, 62, 27, -76, -36, -99, 36, 112, 62, -6, -39, 117, -56, -74, 68, 82, 35, -50, -109, -66, 11, 69, 124, 11, -36, -9, -1},
|
||||||
{-11,-95,82,80,114,-61,-119,-35,-87,38,34,79,-110,5,57,-93,-40,-83,46,53,-56,-86,-14,-114,52,95,67,5,-30,-91,-40,43,-88,-5,-74,11,38,-84,-33,89,-60,64,35,1,23,66,102,54,16,-116,59,51,127,55,20,-103,109,-52,-51,106,77,83,114,-118},
|
{-11, -95, 82, 80, 114, -61, -119, -35, -87, 38, 34, 79, -110, 5, 57, -93, -40, -83, 46, 53, -56, -86, -14, -114, 52, 95, 67, 5, -30, -91, -40, 43, -88, -5, -74, 11, 38, -84, -33, 89, -60, 64, 35, 1, 23, 66, 102, 54, 16, -116, 59, 51, 127, 55, 20, -103, 109, -52, -51, 106, 77, 83, 114, -118},
|
||||||
{-7,-12,-21,-123,-88,-7,115,-14,-81,102,-59,101,-108,-55,18,-101,-54,73,57,-1,116,17,-26,-2,61,-75,18,-47,55,64,-13,25,112,113,32,80,-23,119,84,24,9,25,-82,-115,61,35,117,-20,-2,-83,108,25,31,45,22,-29,-122,-33,44,11,-121,85,52,-4}
|
{-7, -12, -21, -123, -88, -7, 115, -14, -81, 102, -59, 101, -108, -55, 18, -101, -54, 73, 57, -1, 116, 17, -26, -2, 61, -75, 18, -47, 55, 64, -13, 25, 112, 113, 32, 80, -23, 119, 84, 24, 9, 25, -82, -115, 61, 35, 117, -20, -2, -83, 108, 25, 31, 45, 22, -29, -122, -33, 44, 11, -121, 85, 52, -4}
|
||||||
};
|
};
|
||||||
for (int i = 0; i < keys.length; i++) {
|
for (int i = 0; i < 1; i++) {
|
||||||
// String sourceStr = keys[i];
|
// String sourceStr = keys[i];
|
||||||
|
|
||||||
byte[] selT = keys[i];//sourceStr.getBytes(characterSet);
|
byte[] selT = keys[i];
|
||||||
|
|
||||||
// String output = new String(selT, 0, selT.length, characterSet);
|
// String output = new String(selT, 0, selT.length, characterSet);
|
||||||
//
|
//
|
||||||
|
@ -82,23 +87,26 @@ public class SimpleObfuscator {
|
||||||
|
|
||||||
|
|
||||||
byte[] out = soe.obfuscate(selT);
|
byte[] out = soe.obfuscate(selT);
|
||||||
log.append(" {");
|
System.out.println(Arrays.toString(out));
|
||||||
for (int j = 0; j < out.length; j++) {
|
|
||||||
log.append(String.valueOf(out[j]) + ",");
|
|
||||||
}
|
|
||||||
log.append(" }");
|
|
||||||
|
|
||||||
log.append('\t');
|
// log.append(" {");
|
||||||
|
// for (int j = 0; j < out.length; j++) {
|
||||||
|
// log.append(String.valueOf(out[j]) + ",");
|
||||||
|
// }
|
||||||
|
// log.append(" }");
|
||||||
|
//
|
||||||
|
// log.append('\t');
|
||||||
|
|
||||||
byte[] reout = soe.unobfuscate(out);
|
byte[] reout = soe.unobfuscate(selT);
|
||||||
|
|
||||||
|
|
||||||
String outputRe = new String(reout, 0, reout.length, characterSet);
|
// String outputRe = new String(reout, 0, reout.length, characterSet);
|
||||||
|
System.out.println(Arrays.toString(reout));
|
||||||
// if (!sourceStr.equals(outputRe)) {
|
// if (!sourceStr.equals(outputRe)) {
|
||||||
// log.append(" NG\t");
|
// log.append(" NG\t");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
log.append('\n');
|
// log.append('\n');
|
||||||
|
|
||||||
}
|
}
|
||||||
System.out.println(log.toString());
|
System.out.println(log.toString());
|
||||||
|
|
|
@ -0,0 +1,227 @@
|
||||||
|
import com.fasterxml.uuid.Generators;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.LongBuffer;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UUIDUtil {
|
||||||
|
private static final int[] uuidLength = {8, 4, 4, 4, 12};
|
||||||
|
|
||||||
|
|
||||||
|
public static UUID generateUUIDByName(String name) {
|
||||||
|
return Generators.nameBasedGenerator().generate(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static UUID generateUUIDRandomly() {
|
||||||
|
return Generators.randomBasedGenerator().generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID generateUUIDTimely() {
|
||||||
|
|
||||||
|
UUID uuid = Generators.timeBasedGenerator().generate();
|
||||||
|
final ByteBuffer sourceBuffer = ByteBuffer.allocateDirect(16);
|
||||||
|
|
||||||
|
int time_low = (int) (uuid.getMostSignificantBits() >> 32);
|
||||||
|
short time_mid = (short) ((uuid.getMostSignificantBits() >> 16) & 0xffff);
|
||||||
|
short time_high_and_version = (short) ((uuid.getMostSignificantBits()) & 0xffff);
|
||||||
|
short variant_and_sequence = (short) ((uuid.getLeastSignificantBits() >> 48) & 0xffff);
|
||||||
|
short node_most = (short) ((uuid.getLeastSignificantBits() >> 32) & 0xffff);
|
||||||
|
int node_least = (int) uuid.getLeastSignificantBits();
|
||||||
|
|
||||||
|
sourceBuffer.clear();
|
||||||
|
sourceBuffer.putShort(time_high_and_version);
|
||||||
|
sourceBuffer.putShort(time_mid);
|
||||||
|
sourceBuffer.putInt(time_low);
|
||||||
|
sourceBuffer.putShort(variant_and_sequence);
|
||||||
|
sourceBuffer.putShort(node_most);
|
||||||
|
sourceBuffer.putInt(node_least);
|
||||||
|
sourceBuffer.flip();
|
||||||
|
|
||||||
|
// return time_high_and_version + '-' + time_mid + '-' + time_low + '-' + variant_and_sequence + '-' + node;
|
||||||
|
|
||||||
|
return new UUID(sourceBuffer.getLong(), sourceBuffer.getLong());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateUUIDSerialTimely() {
|
||||||
|
final UUID uuid = generateUUIDTimely();
|
||||||
|
return UUIDToString(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String UUIDToBase64(final UUID orgUUID) {
|
||||||
|
if (orgUUID == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final long most = orgUUID.getMostSignificantBits();
|
||||||
|
final long last = orgUUID.getLeastSignificantBits();
|
||||||
|
return new String(Base64.encode(ByteUtil.toBytes(most, last)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static UUID base64ToUUID(final String uuidString) {
|
||||||
|
|
||||||
|
if (uuidString == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] decoded = Base64.decode(uuidString);
|
||||||
|
if (decoded == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final ByteBuffer sourceBuffer = ByteBuffer.allocateDirect(16);
|
||||||
|
sourceBuffer.clear();
|
||||||
|
sourceBuffer.put(decoded);
|
||||||
|
sourceBuffer.flip();
|
||||||
|
return new UUID(sourceBuffer.getLong(), sourceBuffer.getLong());
|
||||||
|
} catch (Exception iae) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String generateUUIDBase58() {
|
||||||
|
final UUID uuid = generateUUIDTimely();
|
||||||
|
return UUIDToBase58(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateUUIDBase58Checked() {
|
||||||
|
final UUID uuid = generateUUIDTimely();
|
||||||
|
return UUIDToBase58Checked(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] UUIDToBytes(final UUID orgUUID) {
|
||||||
|
if (orgUUID == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final long most = orgUUID.getMostSignificantBits();
|
||||||
|
final long last = orgUUID.getLeastSignificantBits();
|
||||||
|
return ByteUtil.toBytes(most, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String UUIDToBase58(final UUID orgUUID) {
|
||||||
|
if (orgUUID == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final long most = orgUUID.getMostSignificantBits();
|
||||||
|
final long last = orgUUID.getLeastSignificantBits();
|
||||||
|
return Base58.encode(ByteUtil.toBytes(most, last));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String UUIDToBase58Checked(final UUID orgUUID) {
|
||||||
|
if (orgUUID == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final long most = orgUUID.getMostSignificantBits();
|
||||||
|
final long last = orgUUID.getLeastSignificantBits();
|
||||||
|
return Base58.encodeChecked(ByteUtil.toBytes(most, last));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID base58ToUUID(final String uuidString) {
|
||||||
|
|
||||||
|
if (uuidString == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
|
||||||
|
final ByteBuffer sourceBuffer = ByteBuffer.allocateDirect(16);
|
||||||
|
sourceBuffer.clear();
|
||||||
|
sourceBuffer.put(Base58.decode(uuidString));
|
||||||
|
sourceBuffer.flip();
|
||||||
|
return new UUID(sourceBuffer.getLong(), sourceBuffer.getLong());
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID base58ToUUIDChecked(final String uuidString) {
|
||||||
|
|
||||||
|
if (uuidString == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] decoded = Base58.decodeChecked(uuidString);
|
||||||
|
if (decoded == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final ByteBuffer sourceBuffer = ByteBuffer.allocateDirect(16);
|
||||||
|
sourceBuffer.clear();
|
||||||
|
sourceBuffer.put(decoded);
|
||||||
|
sourceBuffer.flip();
|
||||||
|
return new UUID(sourceBuffer.getLong(), sourceBuffer.getLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID bytesToUUID(byte[] uuidByte) {
|
||||||
|
if (uuidByte == null || uuidByte.length != 16) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final long most = ByteUtil.fromBytesAsLongMost(uuidByte);
|
||||||
|
final long last = ByteUtil.fromBytesAsLongLast(uuidByte);
|
||||||
|
return new UUID(most, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String UUIDToString(final UUID orgUUID) {
|
||||||
|
|
||||||
|
if (orgUUID == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final CharBuffer sourceBuffer = ByteBuffer.allocateDirect(Character.BYTES * 32).asCharBuffer();
|
||||||
|
sourceBuffer.clear();
|
||||||
|
|
||||||
|
final String orgStr = orgUUID.toString();
|
||||||
|
final StringTokenizer orgStrings = new StringTokenizer(orgStr, "-");
|
||||||
|
while (orgStrings.hasMoreElements()) {
|
||||||
|
sourceBuffer.put(orgStrings.nextToken());
|
||||||
|
}
|
||||||
|
sourceBuffer.flip();
|
||||||
|
return sourceBuffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID stringToUUID(final String uuidString) {
|
||||||
|
if (uuidString == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (uuidString.length()) {
|
||||||
|
case 36:
|
||||||
|
return UUID.fromString(uuidString);
|
||||||
|
case 32:
|
||||||
|
final CharBuffer sourceBuffer = ByteBuffer.allocateDirect(Character.BYTES * uuidString.length()).asCharBuffer();
|
||||||
|
final LongBuffer targetBuffer = ByteBuffer.allocateDirect(Long.BYTES * uuidLength.length).asLongBuffer();
|
||||||
|
sourceBuffer.clear();
|
||||||
|
sourceBuffer.put(uuidString);
|
||||||
|
sourceBuffer.flip();
|
||||||
|
targetBuffer.clear();
|
||||||
|
|
||||||
|
for (int size : uuidLength) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
final char[] buf = new char[size];
|
||||||
|
builder.append("0x");
|
||||||
|
sourceBuffer.get(buf, 0, size);
|
||||||
|
builder.append(buf);
|
||||||
|
targetBuffer.put(Long.decode(builder.toString()));
|
||||||
|
}
|
||||||
|
targetBuffer.flip();
|
||||||
|
long mostSigBits = targetBuffer.get();
|
||||||
|
mostSigBits <<= 16;
|
||||||
|
|
||||||
|
mostSigBits |= targetBuffer.get();
|
||||||
|
mostSigBits <<= 16;
|
||||||
|
|
||||||
|
mostSigBits |= targetBuffer.get();
|
||||||
|
|
||||||
|
long leastSigBits = targetBuffer.get();
|
||||||
|
leastSigBits <<= 48;
|
||||||
|
leastSigBits |= targetBuffer.get();
|
||||||
|
|
||||||
|
return new UUID(mostSigBits, leastSigBits);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue