Last active
June 30, 2023 07:58
-
-
Save panpf/8db42562a80a647b22f2c07e3bdaca2e to your computer and use it in GitHub Desktop.
AES 加解密
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import android.util.Base64; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.security.InvalidAlgorithmParameterException; | |
import java.security.InvalidKeyException; | |
import java.security.Key; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.NoSuchProviderException; | |
import java.security.Provider; | |
import java.security.ProviderException; | |
import java.security.SecureRandom; | |
import java.security.spec.AlgorithmParameterSpec; | |
import javax.crypto.BadPaddingException; | |
import javax.crypto.Cipher; | |
import javax.crypto.IllegalBlockSizeException; | |
import javax.crypto.KeyGenerator; | |
import javax.crypto.NoSuchPaddingException; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.spec.SecretKeySpec; | |
/** | |
* AES 对称加密、解密工具 | |
* <p> | |
* <p> | |
* AES 不支持 NoPadding、PKCS1Padding | |
*/ | |
public class AESHelper { | |
private static final String ALGORITHM = "AES"; | |
private static final String MODE_ECB = "ECB"; | |
private static final String MODE_CBC = "CBC"; | |
private static final String PADDING_PKCS5 = "PKCS5Padding"; | |
private static final String PADDING_PKCS7 = "PKCS7Padding"; | |
private Key key; | |
private String mode; | |
private String padding; | |
private AESHelper(@NonNull Key key, @Nullable String mode, @Nullable String padding) { | |
this.key = key; | |
this.mode = mode; | |
this.padding = padding; | |
} | |
/** | |
* 创建一个秘钥 | |
*/ | |
@NonNull | |
@SuppressWarnings({"WeakerAccess", "unused"}) | |
public static Key createKey(int keySize) { | |
KeyGenerator generator; | |
try { | |
generator = KeyGenerator.getInstance(ALGORITHM); | |
} catch (NoSuchAlgorithmException e) { | |
throw new RuntimeException(e); | |
} | |
generator.init(keySize); | |
return generator.generateKey(); | |
} | |
/** | |
* 根据种子生成一个秘钥,种子可以是任意长度的,固定种子始终生成固定的秘钥 | |
*/ | |
@NonNull | |
@SuppressWarnings({"WeakerAccess", "unused"}) | |
public static Key createKeyBySeed(String seed) { | |
KeyGenerator generator; | |
try { | |
generator = KeyGenerator.getInstance(ALGORITHM); | |
} catch (NoSuchAlgorithmException e) { | |
throw new RuntimeException(e); | |
} | |
SecureRandom random; | |
try { | |
if (android.os.Build.VERSION.SDK_INT >= 24) { | |
// N 以上不支持 Crypto 要自己实现 | |
random = SecureRandom.getInstance("SHA1PRNG", new CryptoProvider()); | |
} else if (android.os.Build.VERSION.SDK_INT >= 17) { | |
// 在 4.2 以上版本中,SecureRandom 获取方式发生了改变 | |
random = SecureRandom.getInstance("SHA1PRNG", "Crypto"); | |
} else { | |
random = SecureRandom.getInstance("SHA1PRNG"); | |
} | |
} catch (NoSuchAlgorithmException | NoSuchProviderException e) { | |
throw new IllegalArgumentException(e); | |
} | |
random.setSeed(seed.getBytes()); | |
generator.init(128, random); | |
return generator.generateKey(); | |
} | |
/** | |
* 秘钥并转换成 BASE64 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static String keyToBase64(Key key) { | |
return Base64.encodeToString(key.getEncoded(), Base64.NO_WRAP); | |
} | |
/** | |
* 秘钥并转换成字节数组 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static byte[] keyToBytes(Key key) { | |
return key.getEncoded(); | |
} | |
/** | |
* 根据密码获取 key | |
* | |
* @param keyBytes 密码 | |
* @return 用密码生成的 key | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static Key keyFromBytes(@NonNull byte[] keyBytes) { | |
return new SecretKeySpec(keyBytes, ALGORITHM); | |
} | |
/** | |
* 根据密码获取 key | |
* | |
* @param passwordBase64 密码使用了 Base64 加密 | |
* @return 用密码生成的 key | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static Key keyFromBase64(@NonNull String passwordBase64) { | |
return new SecretKeySpec(Base64.decode(passwordBase64, Base64.DEFAULT), ALGORITHM); | |
} | |
/** | |
* 创建使用默认 mode 和 padding 的 AESHelper | |
* | |
* @param key 秘钥 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static AESHelper defaultConfig(@NonNull Key key) { | |
return new Builder(key).build(); | |
} | |
/** | |
* 创建 mode 为 ECB 并使用 PKCS5Padding 填充的 AESHelper | |
* | |
* @param key 秘钥 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static AESHelper ecbPKCS5Padding(@NonNull Key key) { | |
return new Builder(key).ecbMode().pkcs5Padding().build(); | |
} | |
/** | |
* 创建 mode 为 ECB 并使用 PKCS7Padding 填充的 AESHelper | |
* | |
* @param key 秘钥 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static AESHelper ecbPKCS7Padding(@NonNull Key key) { | |
return new Builder(key).ecbMode().pkcs7Padding().build(); | |
} | |
/** | |
* 创建 mode 为 CBC 并使用 PKCS5Padding 填充的 AESHelper | |
* | |
* @param key 秘钥 | |
*/ | |
@NonNull | |
@SuppressWarnings({"unused", "WeakerAccess"}) | |
public static AESHelper cbcPKCS5Padding(@NonNull Key key) { | |
return new Builder(key).cbcMode().pkcs5Padding().build(); | |
} | |
/** | |
* 创建 mode 为 CBC 并使用 PKCS7Padding 填充的 AESHelper | |
* | |
* @param key 秘钥 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public static AESHelper cbcPKCS7Padding(@NonNull Key key) { | |
return new Builder(key).cbcMode().pkcs7Padding().build(); | |
} | |
/** | |
* 加密 | |
* | |
* @param textBytes 待加密的明文 | |
* @return 加密后的密文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings("WeakerAccess") | |
public byte[] encrypt(@NonNull byte[] textBytes) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
return createCipher(Cipher.ENCRYPT_MODE).doFinal(textBytes); | |
} | |
/** | |
* 加密 | |
* | |
* @param text 待加密的明文 | |
* @return 加密后的密文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public byte[] encrypt(@NonNull String text) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
return encrypt(text.getBytes()); | |
} | |
/** | |
* 加密并返回 BASE64 字符串 | |
* | |
* @param textBytes 待加密的明文 | |
* @return 加密后的密文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public String encryptToBase64(@NonNull byte[] textBytes) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
return Base64.encodeToString(encrypt(textBytes), Base64.NO_WRAP); | |
} | |
/** | |
* 加密并返回 BASE64 字符串 | |
* | |
* @param text 待加密的明文 | |
* @return 加密后的密文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings({"unused", "WeakerAccess"}) | |
public String encryptToBase64(@NonNull String text) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
return Base64.encodeToString(encrypt(text.getBytes()), Base64.NO_WRAP); | |
} | |
/** | |
* 解密 | |
* | |
* @param cipherTextBytes 待解密的密文 | |
* @return 解密后的明文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings("WeakerAccess") | |
public String decrypt(@NonNull byte[] cipherTextBytes) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
Cipher cipher = createCipher(Cipher.DECRYPT_MODE); | |
byte[] data = cipher.doFinal(cipherTextBytes); | |
return new String(data); | |
} | |
/** | |
* 解密 | |
* | |
* @param cipherText 待解密的密文 | |
* @return 解密后的明文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public String decrypt(@NonNull String cipherText) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
return decrypt(cipherText.getBytes()); | |
} | |
/** | |
* 解密使用了 BASE64 转码的密文 | |
* | |
* @param cipherTextBytes 待解密的密文 | |
* @return 解密后的明文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings("unused") | |
public String decryptFromBase64(@NonNull byte[] cipherTextBytes) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
return decrypt(Base64.decode(cipherTextBytes, Base64.DEFAULT)); | |
} | |
/** | |
* 解密使用了 BASE64 转码的密文 | |
* | |
* @param cipherText 待解密的密文 | |
* @return 解密后的明文 | |
* @throws InvalidKeyException 密码无效 | |
* @throws BadPaddingException 密码错误 | |
* @throws IllegalBlockSizeException 密码长度和密文长度不匹配,请检查密码长度个密文长度 | |
*/ | |
@NonNull | |
@SuppressWarnings({"unused", "WeakerAccess"}) | |
public String decryptFromBase64(@NonNull String cipherText) throws InvalidKeyException, | |
BadPaddingException, IllegalBlockSizeException { | |
return decrypt(Base64.decode(cipherText.getBytes(), Base64.DEFAULT)); | |
} | |
@NonNull | |
private Cipher createCipher(int opMode) throws InvalidKeyException { | |
String cipherAlgorithm; | |
if (mode == null || padding == null) { | |
cipherAlgorithm = ALGORITHM; | |
} else { | |
cipherAlgorithm = String.format("%s/%s/%s", ALGORITHM, mode, padding); | |
} | |
Cipher cipher; | |
try { | |
cipher = Cipher.getInstance(cipherAlgorithm); | |
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) { | |
throw new IllegalArgumentException(e); | |
} | |
AlgorithmParameterSpec spec = null; | |
if (MODE_CBC.equals(mode)) { | |
spec = new IvParameterSpec(new byte[cipher.getBlockSize()]); | |
} | |
try { | |
cipher.init(opMode, key, spec); | |
} catch (InvalidAlgorithmParameterException e) { | |
throw new IllegalArgumentException(e); | |
} | |
return cipher; | |
} | |
private static class Builder { | |
private Key key; | |
private String mode; | |
private String padding; | |
private Builder(@NonNull Key key) { | |
this.key = key; | |
} | |
@NonNull | |
@SuppressWarnings({"unused", "WeakerAccess"}) | |
public Builder ecbMode() { | |
mode = MODE_ECB; | |
return this; | |
} | |
@NonNull | |
@SuppressWarnings({"unused", "WeakerAccess"}) | |
public Builder cbcMode() { | |
mode = MODE_CBC; | |
return this; | |
} | |
@NonNull | |
@SuppressWarnings({"unused", "WeakerAccess"}) | |
public Builder pkcs5Padding() { | |
padding = PADDING_PKCS5; | |
return this; | |
} | |
@NonNull | |
@SuppressWarnings({"unused", "WeakerAccess"}) | |
public Builder pkcs7Padding() { | |
padding = PADDING_PKCS7; | |
return this; | |
} | |
@SuppressWarnings("WeakerAccess") | |
@NonNull | |
public AESHelper build() { | |
return new AESHelper(key, mode, padding); | |
} | |
} | |
/** | |
* from: https://android.googlesource.com/platform/libcore-snapshot/+/ics-mr1/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java | |
*/ | |
private static class CryptoProvider extends Provider { | |
private static final long serialVersionUID = 7991202868423459598L; | |
/** | |
* Creates a Provider and puts parameters | |
*/ | |
public CryptoProvider() { | |
super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)"); | |
// names of classes implementing services | |
final String MD_NAME = "org.apache.harmony.security.provider.crypto.SHA1_MessageDigestImpl"; | |
final String SR_NAME = "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl"; | |
final String SIGN_NAME = "org.apache.harmony.security.provider.crypto.SHA1withDSA_SignatureImpl"; | |
final String SIGN_ALIAS = "SHA1withDSA"; | |
final String KEYF_NAME = "org.apache.harmony.security.provider.crypto.DSAKeyFactoryImpl"; | |
put("MessageDigest.SHA-1", MD_NAME); | |
put("MessageDigest.SHA-1 ImplementedIn", "Software"); | |
put("Alg.Alias.MessageDigest.SHA1", "SHA-1"); | |
put("Alg.Alias.MessageDigest.SHA", "SHA-1"); | |
if (RandomBitsSupplier.isServiceAvailable()) { | |
put("SecureRandom.SHA1PRNG", SR_NAME); | |
put("SecureRandom.SHA1PRNG ImplementedIn", "Software"); | |
} | |
put("Signature.SHA1withDSA", SIGN_NAME); | |
put("Signature.SHA1withDSA ImplementedIn", "Software"); | |
put("Alg.Alias.Signature.SHAwithDSA", SIGN_ALIAS); | |
put("Alg.Alias.Signature.DSAwithSHA1", SIGN_ALIAS); | |
put("Alg.Alias.Signature.SHA1/DSA", SIGN_ALIAS); | |
put("Alg.Alias.Signature.SHA/DSA", SIGN_ALIAS); | |
put("Alg.Alias.Signature.SHA-1/DSA", SIGN_ALIAS); | |
put("Alg.Alias.Signature.DSA", SIGN_ALIAS); | |
put("Alg.Alias.Signature.DSS", SIGN_ALIAS); | |
put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", SIGN_ALIAS); | |
put("Alg.Alias.Signature.1.2.840.10040.4.3", SIGN_ALIAS); | |
put("Alg.Alias.Signature.1.3.14.3.2.13", SIGN_ALIAS); | |
put("Alg.Alias.Signature.1.3.14.3.2.27", SIGN_ALIAS); | |
put("KeyFactory.DSA", KEYF_NAME); | |
put("KeyFactory.DSA ImplementedIn", "Software"); | |
put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); | |
put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA"); | |
} | |
} | |
/** | |
* from: https://android.googlesource.com/platform/libcore-snapshot/+/ics-mr1/luni/src/main/java/org/apache/harmony/security/provider/crypto/RandomBitsSupplier.java | |
*/ | |
private static class RandomBitsSupplier { | |
/** | |
* names of random devices on Linux platform | |
*/ | |
private static final String DEVICE_NAMES[] = {"/dev/urandom" /*, "/dev/random" */}; | |
/** | |
* InputStream to read from device | |
* <p> | |
* Using a BufferedInputStream leads to problems | |
* on Android in rare cases, since the | |
* BufferedInputStream's available() issues an | |
* ioctl(), and the pseudo device doesn't seem | |
* to like that. Since we're reading bigger | |
* chunks and not single bytes, the FileInputStream | |
* shouldn't be slower, so we use that. Same might | |
* apply to other Linux platforms. | |
* <p> | |
* TODO: the above doesn't sound true. | |
*/ | |
private static FileInputStream fis = null; | |
/** | |
* File to connect to device | |
*/ | |
private static File randomFile = null; | |
/** | |
* value of field is "true" only if a device is available | |
*/ | |
private static boolean serviceAvailable = false; | |
static { | |
for (String deviceName : DEVICE_NAMES) { | |
try { | |
File file = new File(deviceName); | |
if (file.canRead()) { | |
fis = new FileInputStream(file); | |
randomFile = file; | |
serviceAvailable = true; | |
} | |
} catch (FileNotFoundException e) { | |
} | |
} | |
} | |
/** | |
* The method is called by provider to determine if a device is available. | |
*/ | |
static boolean isServiceAvailable() { | |
return serviceAvailable; | |
} | |
/** | |
* On platforms with "random" devices available, | |
* the method reads random bytes from the device. <BR> | |
* <p> | |
* In case of any runtime failure ProviderException gets thrown. | |
*/ | |
private static synchronized byte[] getUnixDeviceRandom(int numBytes) { | |
byte[] bytes = new byte[numBytes]; | |
int total = 0; | |
int bytesRead; | |
int offset = 0; | |
try { | |
for (; ; ) { | |
bytesRead = fis.read(bytes, offset, numBytes - total); | |
// the below case should not occur because /dev/random or /dev/urandom is a special file | |
// hence, if it is happened there is some internal problem | |
if (bytesRead == -1) { | |
throw new ProviderException("bytesRead == -1"); | |
} | |
total += bytesRead; | |
offset += bytesRead; | |
if (total >= numBytes) { | |
break; | |
} | |
} | |
} catch (IOException e) { | |
// actually there should be no IOException because device is a special file; | |
// hence, there is either some internal problem or, for instance, | |
// device was removed in runtime, or something else | |
throw new ProviderException("ATTENTION: IOException in RandomBitsSupplier.getLinuxRandomBits(): " + e); | |
} | |
return bytes; | |
} | |
/** | |
* The method returns byte array of requested length provided service is available. | |
* ProviderException gets thrown otherwise. | |
* | |
* @param numBytes - length of bytes requested | |
* @return byte array | |
* @throws IllegalArgumentException - if numBytes <= 0 | |
*/ | |
public static byte[] getRandomBits(int numBytes) { | |
if (numBytes <= 0) { | |
throw new IllegalArgumentException(Integer.toString(numBytes)); | |
} | |
// We have been unable to get a random device or fall back to the | |
// native security module code - throw an exception. | |
if (!serviceAvailable) { | |
throw new ProviderException("ATTENTION: service is not available : no random devices"); | |
} | |
return getUnixDeviceRandom(numBytes); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.support.test.filters.LargeTest; | |
import android.support.test.runner.AndroidJUnit4; | |
import com.yingyonghui.market.util.AESHelper; | |
import org.junit.Assert; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import java.security.InvalidKeyException; | |
import java.security.Key; | |
import java.security.spec.InvalidKeySpecException; | |
import javax.crypto.BadPaddingException; | |
import javax.crypto.IllegalBlockSizeException; | |
@RunWith(AndroidJUnit4.class) | |
@LargeTest | |
public class AESHelperTest { | |
private static final String SOURCE = "小红那年七岁,她跟着爸妈去赶集,站在一个卖童装的摊位旁边,盯着那条裙子,无论如何都不肯走。\n" + | |
"\n" + | |
"她太想要这样一条裙子了,或者说白了,她想要一件新衣服,一件不是妈妈手工做的,而是商店里买来的衣服。\n" + | |
"\n" + | |
"她听见已经走出了几步的妈妈跟站得更远的爸爸说,“这孩子到底随谁呢?才这么大就这么臭美?我们家里人哪有这种样子的?能不能要点脸?”\n" + | |
"\n" + | |
"爸爸已经非常烦躁,走上前来,不由分说劈头给了她一个耳光,“就知道穿穿穿,打扮那么排场出去干什么?”\n" + | |
"\n" + | |
"她哇地一声哭了,妈妈倒是很恼怒地跑过来拉住爸爸,“你有病吗?谁让你打她了?”\n" + | |
"\n" + | |
"可是裙子最终还是没买。她反而成了全家人的笑柄,一直到很多年后,妈妈提起她小时候,还是笑得肚子疼,“一丁点儿大,臭美得很!”\n" + | |
"\n" + | |
"然后有兄弟姐妹在旁边起哄揶揄她\n" + | |
"\n" + | |
"作者:kongguyouling\n" + | |
"链接:http://www.jianshu.com/p/c60af04614af\n" + | |
"來源:简书\n" + | |
"著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。"; | |
@Test | |
public void testBytesAndBase64() throws InvalidKeySpecException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { | |
AESHelper aesHelper = AESHelper.ecbPKCS5Padding(AESHelper.createKey(128)); | |
Assert.assertEquals("【AES】Bytes encrypt and decrypt test failed", SOURCE, aesHelper.decrypt(aesHelper.encrypt(SOURCE.getBytes()))); | |
Assert.assertEquals("【AES】Base64 encrypt and decrypt test failed", SOURCE, aesHelper.decryptFromBase64(aesHelper.encryptToBase64(SOURCE))); | |
} | |
@Test | |
public void testModeAndPadding() throws InvalidKeySpecException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { | |
byte[] sourceBytes = SOURCE.getBytes(); | |
Key key = AESHelper.createKey(128); | |
AESHelper aesHelper = AESHelper.defaultConfig(key); | |
String decryptResult = aesHelper.decrypt(aesHelper.encrypt(sourceBytes)); | |
Assert.assertEquals("【AES】default encrypt and decrypt test failed", SOURCE, decryptResult); | |
AESHelper ebcPacks5PaddingAesHelper = AESHelper.ecbPKCS5Padding(key); | |
String ebcPacks5PaddingDecryptResult = ebcPacks5PaddingAesHelper.decrypt(ebcPacks5PaddingAesHelper.encrypt(sourceBytes)); | |
Assert.assertEquals("【AES】ebcPacks5Padding encrypt and decrypt test failed", SOURCE, ebcPacks5PaddingDecryptResult); | |
AESHelper ebcPacks7PaddingAesHelper = AESHelper.ecbPKCS7Padding(key); | |
String ebcPacks7PaddingDecryptResult = ebcPacks7PaddingAesHelper.decrypt(ebcPacks7PaddingAesHelper.encrypt(sourceBytes)); | |
Assert.assertEquals("【AES】ebcPacks7Padding encrypt and decrypt test failed", SOURCE, ebcPacks7PaddingDecryptResult); | |
AESHelper cbcPacks5PaddingAesHelper = AESHelper.cbcPKCS5Padding(key); | |
String cbcPacks5PaddingDecryptResult = cbcPacks5PaddingAesHelper.decrypt(cbcPacks5PaddingAesHelper.encrypt(sourceBytes)); | |
Assert.assertEquals("【AES】cbcPacks5Padding encrypt and decrypt test failed", SOURCE, cbcPacks5PaddingDecryptResult); | |
AESHelper cbcPacks7PaddingAesHelper = AESHelper.cbcPKCS7Padding(key); | |
String cbcPacks7PaddingDecryptResult = cbcPacks7PaddingAesHelper.decrypt(cbcPacks7PaddingAesHelper.encrypt(sourceBytes)); | |
Assert.assertEquals("【AES】cbcPacks7Padding encrypt and decrypt test failed", SOURCE, cbcPacks7PaddingDecryptResult); | |
} | |
@Test | |
public void testErrorPassword() throws InvalidKeySpecException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { | |
AESHelper aesHelper = AESHelper.ecbPKCS5Padding(AESHelper.createKey(128)); | |
AESHelper errorAesHelper = AESHelper.ecbPKCS5Padding(AESHelper.createKey(128)); | |
String encryptResult = aesHelper.encryptToBase64(SOURCE); | |
String errorDecryptResult = null; | |
try { | |
errorDecryptResult = errorAesHelper.decryptFromBase64(encryptResult); | |
} catch (BadPaddingException e) { | |
e.printStackTrace(); | |
} | |
Assert.assertNotEquals("【AES】eTest error password failed", SOURCE, errorDecryptResult); | |
} | |
@Test | |
public void testCreateKeyBySeed() { | |
String seed = "" + System.currentTimeMillis(); | |
String key1 = AESHelper.keyToBase64(AESHelper.createKeyBySeed(seed)); | |
String key2 = AESHelper.keyToBase64(AESHelper.createKeyBySeed(seed)); | |
Assert.assertEquals("Test create key by seed failed", key1, key2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment