mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-24 18:04:54 +08:00
fix code
This commit is contained in:
parent
c2d419ffdc
commit
ba2813becb
@ -12,6 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.core.util;
|
||||
|
||||
import org.dromara.hutool.core.io.buffer.FastByteBuffer;
|
||||
import org.dromara.hutool.core.math.NumberUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@ -608,4 +609,24 @@ public class ByteUtil {
|
||||
}
|
||||
return new BigInteger(1, mag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接多个byte[]
|
||||
*
|
||||
* @param byteArrays 多个byte[]
|
||||
* @return 连接后的byte[]
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static byte[] concat(final byte[]... byteArrays){
|
||||
int totalLength = 0;
|
||||
for (final byte[] byteArray : byteArrays) {
|
||||
totalLength += byteArray.length;
|
||||
}
|
||||
|
||||
final FastByteBuffer buffer = new FastByteBuffer(totalLength);
|
||||
for (final byte[] byteArray : byteArrays) {
|
||||
buffer.append(byteArray);
|
||||
}
|
||||
return buffer.toArrayZeroCopyIfPossible();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.crypto.symmetric;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.ByteUtil;
|
||||
import org.dromara.hutool.crypto.digest.MD5;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* OpenSSL中加盐解析器<br>
|
||||
* 参考:
|
||||
* <pre>
|
||||
* https://stackoverflow.com/questions/11783062/how-to-decrypt-file-in-java-encrypted-with-openssl-command-using-aes
|
||||
* https://stackoverflow.com/questions/32508961/java-equivalent-of-an-openssl-aes-cbc-encryption
|
||||
* </pre>
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class OpenSSLSaltParser {
|
||||
private final static byte SALT_LEN = 8;
|
||||
|
||||
/**
|
||||
* OpenSSL's magic initial bytes.
|
||||
*/
|
||||
private static final byte[] SALTED_MAGIC = "Salted__".getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
/**
|
||||
* 获取魔术值和随机盐的长度:16(128位)
|
||||
*/
|
||||
public static final int MAGIC_SALT_LENGTH = SALTED_MAGIC.length + SALT_LEN;
|
||||
|
||||
/**
|
||||
* 获取去除头部盐的加密数据<br>
|
||||
*
|
||||
* @param encryptedData 密文
|
||||
* @return 实际密文
|
||||
*/
|
||||
public static byte[] getData(final byte[] encryptedData) {
|
||||
if (ArrayUtil.startWith(encryptedData, SALTED_MAGIC)) {
|
||||
return Arrays.copyOfRange(encryptedData, SALTED_MAGIC.length + SALT_LEN, encryptedData.length);
|
||||
}
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取8位salt随机数<br>
|
||||
*
|
||||
* @param encryptedData 密文
|
||||
* @return salt随机数
|
||||
*/
|
||||
public static byte[] getSalt(final byte[] encryptedData) {
|
||||
if (ArrayUtil.startWith(encryptedData, SALTED_MAGIC)) {
|
||||
return Arrays.copyOfRange(encryptedData, SALTED_MAGIC.length, MAGIC_SALT_LENGTH);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为加密后的数据添加Magic头,生成的密文格式为:
|
||||
* <pre>
|
||||
* Salted__[salt][data]
|
||||
* </pre>
|
||||
*
|
||||
* @param data 数据
|
||||
* @param salt 加盐值,必须8位,{@code null}表示返回原文
|
||||
* @return 密文
|
||||
*/
|
||||
public static byte[] addMagic(final byte[] data, final byte[] salt) {
|
||||
if (null == salt) {
|
||||
return data;
|
||||
}
|
||||
Assert.isTrue(SALT_LEN == salt.length);
|
||||
return ByteUtil.concat(SALTED_MAGIC, salt, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Magic头,生成的密文格式为:
|
||||
* <pre>
|
||||
* Salted__[salt]
|
||||
* </pre>
|
||||
*
|
||||
* @param salt 加盐值,必须8位,不能为{@code null}
|
||||
* @return Magic头
|
||||
*/
|
||||
public static byte[] getSaltedMagic(final byte[] salt) {
|
||||
return ByteUtil.concat(SALTED_MAGIC, salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建MD5 OpenSSLSaltParser
|
||||
*
|
||||
* @param keyLength 密钥长度
|
||||
* @param algorithm 算法
|
||||
* @return OpenSSLSaltParser
|
||||
*/
|
||||
public static OpenSSLSaltParser ofMd5(final int keyLength, final String algorithm) {
|
||||
return of(new MD5().getDigest(), keyLength, algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建OpenSSLSaltParser
|
||||
*
|
||||
* @param digest {@link MessageDigest}
|
||||
* @param keyLength 密钥长度
|
||||
* @param algorithm 算法
|
||||
* @return OpenSSLSaltParser
|
||||
*/
|
||||
public static OpenSSLSaltParser of(final MessageDigest digest, final int keyLength, final String algorithm) {
|
||||
return new OpenSSLSaltParser(digest, keyLength, algorithm);
|
||||
}
|
||||
|
||||
private final MessageDigest digest;
|
||||
private final int keyLength;
|
||||
private final int ivLength;
|
||||
private String algorithm;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param digest {@link MessageDigest}
|
||||
* @param keyLength 密钥长度
|
||||
* @param algorithm 算法
|
||||
*/
|
||||
public OpenSSLSaltParser(final MessageDigest digest, final int keyLength, final String algorithm) {
|
||||
int ivLength = 16;
|
||||
if (StrUtil.containsIgnoreCase(algorithm, "des")) {
|
||||
ivLength = 8;
|
||||
}
|
||||
this.digest = digest;
|
||||
this.keyLength = keyLength;
|
||||
this.ivLength = ivLength;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param digest {@link MessageDigest}
|
||||
* @param keyLength 密钥长度
|
||||
* @param ivLength IV长度
|
||||
*/
|
||||
public OpenSSLSaltParser(final MessageDigest digest, final int keyLength, final int ivLength) {
|
||||
this.digest = digest;
|
||||
this.keyLength = keyLength;
|
||||
this.ivLength = ivLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过密钥和salt值,获取实际的密钥
|
||||
*
|
||||
* @param pass 密钥
|
||||
* @param salt 加盐值
|
||||
* @return 实际密钥
|
||||
*/
|
||||
public byte[][] getKeyAndIV(final byte[] pass, final byte[] salt) {
|
||||
final byte[][] keyAndIvResult = new byte[2][];
|
||||
if (null == salt) {
|
||||
keyAndIvResult[0] = pass;
|
||||
return keyAndIvResult;
|
||||
}
|
||||
Assert.isTrue(SALT_LEN == salt.length);
|
||||
|
||||
final byte[] passAndSalt = ByteUtil.concat(pass, salt);
|
||||
|
||||
byte[] hash = new byte[0];
|
||||
byte[] keyAndIv = new byte[0];
|
||||
for (int i = 0; i < 3 && keyAndIv.length < keyLength + ivLength; i++) {
|
||||
final byte[] hashData = ByteUtil.concat(hash, passAndSalt);
|
||||
hash = digest.digest(hashData);
|
||||
keyAndIv = ByteUtil.concat(keyAndIv, hash);
|
||||
}
|
||||
|
||||
keyAndIvResult[0] = Arrays.copyOfRange(keyAndIv, 0, keyLength);
|
||||
if (!StrUtil.containsAnyIgnoreCase(algorithm, "RC", "DES")) {
|
||||
keyAndIvResult[1] = Arrays.copyOfRange(keyAndIv, keyLength, keyLength + ivLength);
|
||||
}
|
||||
return keyAndIvResult;
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.crypto.symmetric;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.crypto.digest.DigestUtil;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* OpenSSL风格前缀和加盐相关工具类<br>
|
||||
* 参考:https://stackoverflow.com/questions/32508961/java-equivalent-of-an-openssl-aes-cbc-encryption
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class SaltUtil {
|
||||
|
||||
private final static byte SALT_LEN = 8;
|
||||
private final static byte IV_LEN = 16;
|
||||
private final static byte KEY_LEN = 32;
|
||||
|
||||
/**
|
||||
* OpenSSL's magic initial bytes.
|
||||
*/
|
||||
private static final byte[] SALTED_MAGIC = "Salted__".getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
/**
|
||||
* 获取8位salt随机数<br>
|
||||
*
|
||||
* @param encryptedData 密文
|
||||
* @return salt随机数
|
||||
*/
|
||||
public static byte[] getSalt(final byte[] encryptedData) {
|
||||
if (ArrayUtil.startWith(encryptedData, SALTED_MAGIC)) {
|
||||
return Arrays.copyOfRange(encryptedData, SALTED_MAGIC.length, SALTED_MAGIC.length + SALT_LEN);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过密钥和salt值,获取实际的密钥
|
||||
*
|
||||
* @param pass 密钥
|
||||
* @param salt 加盐值
|
||||
* @return 实际密钥
|
||||
*/
|
||||
public static byte[] getKey(final byte[] pass, final byte[] salt) {
|
||||
if (null == salt) {
|
||||
return pass;
|
||||
}
|
||||
final byte[] passAndSalt = arrayConcat(pass, salt);
|
||||
|
||||
byte[] hash = new byte[0];
|
||||
byte[] keyAndIv = new byte[0];
|
||||
for (int i = 0; i < 3 && keyAndIv.length < 48; i++) {
|
||||
final byte[] hashData = arrayConcat(hash, passAndSalt);
|
||||
hash = DigestUtil.md5(hashData);
|
||||
keyAndIv = arrayConcat(keyAndIv, hash);
|
||||
}
|
||||
|
||||
return Arrays.copyOfRange(keyAndIv, 0, KEY_LEN);
|
||||
}
|
||||
|
||||
private static byte[] arrayConcat(final byte[] a, final byte[] b) {
|
||||
if (ArrayUtil.isEmpty(a)) {
|
||||
return b;
|
||||
}
|
||||
final byte[] c = new byte[a.length + b.length];
|
||||
System.arraycopy(a, 0, c, 0, a.length);
|
||||
System.arraycopy(b, 0, c, a.length, b.length);
|
||||
return c;
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ package org.dromara.hutool.crypto.symmetric;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
import org.dromara.hutool.core.lang.Opt;
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.codec.HexUtil;
|
||||
@ -32,10 +33,7 @@ import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.io.*;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.SecureRandom;
|
||||
@ -65,7 +63,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
|
||||
private boolean isZeroPadding;
|
||||
private final Lock lock = new ReentrantLock();
|
||||
|
||||
// ------------------------------------------------------------------ Constructor start
|
||||
// region ----- Constructor
|
||||
|
||||
/**
|
||||
* 构造,使用随机密钥
|
||||
@ -140,7 +138,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
|
||||
initParams(algorithm, paramsSpec);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ Constructor end
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
@ -234,9 +232,20 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
|
||||
* @since 5.7.12
|
||||
*/
|
||||
public SymmetricCrypto setMode(final CipherMode mode) {
|
||||
return setMode(mode, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化模式并清空数据
|
||||
*
|
||||
* @param mode 模式枚举
|
||||
* @param salt 加盐值,用于
|
||||
* @return this
|
||||
*/
|
||||
public SymmetricCrypto setMode(final CipherMode mode, final byte[] salt) {
|
||||
lock.lock();
|
||||
try {
|
||||
initMode(mode.getValue());
|
||||
initMode(mode.getValue(), salt);
|
||||
} catch (final Exception e) {
|
||||
throw new CryptoException(e);
|
||||
} finally {
|
||||
@ -281,23 +290,39 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
|
||||
|
||||
@Override
|
||||
public byte[] encrypt(final byte[] data) {
|
||||
return encrypt(data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param data 被加密的bytes
|
||||
* @param salt 加盐值,如果为{@code null}不设置,否则生成带Salted__头的密文数据
|
||||
* @return 加密后的bytes
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public byte[] encrypt(final byte[] data, final byte[] salt) {
|
||||
lock.lock();
|
||||
|
||||
byte[] result;
|
||||
try {
|
||||
final Cipher cipher = initMode(Cipher.ENCRYPT_MODE);
|
||||
return cipher.doFinal(paddingDataWithZero(data, cipher.getBlockSize()));
|
||||
final Cipher cipher = initMode(Cipher.ENCRYPT_MODE, salt);
|
||||
result = cipher.doFinal(paddingDataWithZero(data, cipher.getBlockSize()));
|
||||
} catch (final Exception e) {
|
||||
throw new CryptoException(e);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return OpenSSLSaltParser.addMagic(result, salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encrypt(final InputStream data, final OutputStream out, final boolean isClose) throws IORuntimeException {
|
||||
lock.lock();
|
||||
|
||||
CipherOutputStream cipherOutputStream = null;
|
||||
try {
|
||||
final Cipher cipher = initMode(Cipher.ENCRYPT_MODE);
|
||||
final Cipher cipher = initMode(Cipher.ENCRYPT_MODE, null);
|
||||
cipherOutputStream = new CipherOutputStream(out, cipher);
|
||||
final long length = IoUtil.copy(data, cipherOutputStream);
|
||||
if (this.isZeroPadding) {
|
||||
@ -335,11 +360,11 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
|
||||
final byte[] decryptData;
|
||||
|
||||
lock.lock();
|
||||
|
||||
final byte[] salt = OpenSSLSaltParser.getSalt(bytes);
|
||||
try {
|
||||
final Cipher cipher = initMode(Cipher.DECRYPT_MODE);
|
||||
final Cipher cipher = initMode(Cipher.DECRYPT_MODE, salt);
|
||||
blockSize = cipher.getBlockSize();
|
||||
decryptData = cipher.doFinal(bytes);
|
||||
decryptData = cipher.doFinal(OpenSSLSaltParser.getData(bytes));
|
||||
} catch (final Exception e) {
|
||||
throw new CryptoException(e);
|
||||
} finally {
|
||||
@ -354,7 +379,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
|
||||
lock.lock();
|
||||
CipherInputStream cipherInputStream = null;
|
||||
try {
|
||||
final Cipher cipher = initMode(Cipher.DECRYPT_MODE);
|
||||
final Cipher cipher = initMode(Cipher.DECRYPT_MODE, null);
|
||||
cipherInputStream = new CipherInputStream(data, cipher);
|
||||
if (this.isZeroPadding) {
|
||||
final int blockSize = cipher.getBlockSize();
|
||||
@ -424,8 +449,19 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
|
||||
* @throws InvalidKeyException 无效key
|
||||
* @throws InvalidAlgorithmParameterException 无效算法
|
||||
*/
|
||||
private Cipher initMode(final int mode) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
return this.cipherWrapper.initMode(mode, this.secretKey).getRaw();
|
||||
private Cipher initMode(final int mode, final byte[] salt) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
SecretKey secretKey = this.secretKey;
|
||||
if (null != salt) {
|
||||
// /issues#I6YWWD,提供OpenSSL格式兼容支持
|
||||
final String algorithm = getCipher().getAlgorithm();
|
||||
final byte[][] keyAndIV = OpenSSLSaltParser.ofMd5(32, algorithm)
|
||||
.getKeyAndIV(secretKey.getEncoded(), salt);
|
||||
secretKey = KeyUtil.generateKey(algorithm, keyAndIV[0]);
|
||||
if(ArrayUtil.isNotEmpty(keyAndIV[1])){
|
||||
this.cipherWrapper.setParams(new IvParameterSpec(keyAndIV[1]));
|
||||
}
|
||||
}
|
||||
return this.cipherWrapper.initMode(mode, secretKey).getRaw();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,11 +69,4 @@ public class RC4Test {
|
||||
final String msg2 = SymmetricCrypto.decryptStr(encryptHex2);
|
||||
Assertions.assertEquals(message2, msg2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void decryptTest() {
|
||||
GlobalProviderFactory.setUseCustomProvider(false);
|
||||
final String key16 = "1234567890123456";
|
||||
final SymmetricCrypto aes = new SymmetricCrypto("SymmetricCrypto", key16.getBytes());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.crypto.symmetric;
|
||||
|
||||
import org.dromara.hutool.crypto.KeyUtil;
|
||||
import org.dromara.hutool.crypto.SecureUtil;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
public class SaltUtilTest {
|
||||
|
||||
/**
|
||||
* 测试:
|
||||
* https://www.bejson.com/enc/aesdes/
|
||||
*/
|
||||
@Test
|
||||
void rc4Test() {
|
||||
final String encrypted = "U2FsdGVkX19DSROPe0+Ejkw84osqWw==";
|
||||
|
||||
final byte[] salt = OpenSSLSaltParser.getSalt(SecureUtil.decode(encrypted));
|
||||
Assertions.assertNotNull(salt);
|
||||
|
||||
final byte[][] keyAndIV = OpenSSLSaltParser.ofMd5(32, "RC4")
|
||||
.getKeyAndIV("1234567890123456".getBytes(), salt);
|
||||
Assertions.assertNotNull(keyAndIV);
|
||||
Assertions.assertNotNull(keyAndIV[0]);
|
||||
|
||||
final SecretKey rc4Key = KeyUtil.generateKey("RC4", keyAndIV[0]);
|
||||
Assertions.assertNotNull(rc4Key);
|
||||
|
||||
final byte[] data = OpenSSLSaltParser.getData(SecureUtil.decode(encrypted));
|
||||
|
||||
final SymmetricCrypto rc4 = new SymmetricCrypto("RC4", rc4Key);
|
||||
final String decrypt = rc4.decryptStr(data);
|
||||
Assertions.assertEquals("hutool", decrypt);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试:
|
||||
* https://www.bejson.com/enc/aesdes/
|
||||
*/
|
||||
@Test
|
||||
void rc4Test2() {
|
||||
final String encrypted = "U2FsdGVkX19DSROPe0+Ejkw84osqWw==";
|
||||
final SymmetricCrypto rc4 = new SymmetricCrypto("RC4", "1234567890123456".getBytes());
|
||||
final String decrypt = rc4.decryptStr(encrypted);
|
||||
Assertions.assertEquals("hutool", decrypt);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试:
|
||||
* https://www.bejson.com/enc/aesdes/
|
||||
*/
|
||||
@Test
|
||||
void aesTest() {
|
||||
final String encrypted = "U2FsdGVkX1+lqsuKAR+OdOeNduvx5wgXf6yEUdDIh3g=";
|
||||
final SymmetricCrypto des = new SymmetricCrypto("AES/CBC/PKCS5Padding", "1234567890123456".getBytes());
|
||||
final String decrypt = des.decryptStr(encrypted);
|
||||
Assertions.assertEquals("hutool", decrypt);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user