提交 ee374d26 编写于 作者: Z zhangshuang

Merge branch 'release/2.0.3' into feature/LC-stability

* release/2.0.3:
  upgraded version to 2.0.3.RELEASE;
  fixed the bugs of AESUtils: incorrect process the offset of the plain or cipher bytes specified by argument;
  fixed the wrong version;
  upgraded version to 2.0.2;

# Conflicts:
#	pom.xml
......@@ -5,12 +5,12 @@
<parent>
<groupId>com.jd.blockchain</groupId>
<artifactId>jdchain-parent</artifactId>
<version>1.1.4.RELEASE</version>
<relativePath>../../project/parent</relativePath>
<version>1.1.5.RELEASE</version>
<relativePath>../project/parent</relativePath>
</parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
<packaging>pom</packaging>
<modules>
......
......@@ -5,7 +5,7 @@
<parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
</parent>
<artifactId>utils-common</artifactId>
......
......@@ -5,7 +5,7 @@
<parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
</parent>
<artifactId>utils-crypto-base</artifactId>
......
......@@ -5,7 +5,7 @@
<parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
</parent>
<artifactId>utils-crypto-classic</artifactId>
......
......@@ -7,7 +7,6 @@ import org.bouncycastle.crypto.CipherKeyGenerator;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
......@@ -132,31 +131,41 @@ public class AESUtils {
}
// To get the value padded into input
int padding = 16 - length % BLOCK_SIZE;
// The plaintext with padding value
byte[] plainBytesWithPadding = new byte[length + padding];
System.arraycopy(plainBytes, offset, plainBytesWithPadding, 0, length);
// The padder adds PKCS7 padding to the input, which makes its length to
// become an integral multiple of 16 bytes
PKCS7Padding padder = new PKCS7Padding();
// To add padding
padder.addPadding(plainBytesWithPadding, length);
byte padding = getAESPadding(length);
int lengthWithPadding = length + padding;
// 加密的明文输入数组,有 2 部分组成:原始明文 + PKCS7填充;
byte[] input = new byte[lengthWithPadding];
System.arraycopy(plainBytes, offset, input, 0, length);
// PKCS7填充;
PKCS7PaddingUtils.addPadding(input, length, padding);
// 加密的密文输出数组,由 2 部分组成:IV + 密文;
byte[] output = new byte[IV_SIZE + lengthWithPadding];
// The IV locates on the first block of ciphertext
System.arraycopy(iv, 0, output, 0, IV_SIZE);
CBCBlockCipher encryptor = new CBCBlockCipher(new AESEngine());
// To provide key and initialisation vector as input
encryptor.init(true, new ParametersWithIV(new KeyParameter(secretKey), iv));
byte[] output = new byte[plainBytesWithPadding.length + IV_SIZE];
// To encrypt the input_p in CBC mode
int blockCount = plainBytesWithPadding.length / BLOCK_SIZE;
int blockCount = lengthWithPadding / BLOCK_SIZE;
int blockOffset;
for (int i = 0; i < blockCount; i++) {
encryptor.processBlock(plainBytesWithPadding, i * BLOCK_SIZE, output, (i + 1) * BLOCK_SIZE);
blockOffset = i * BLOCK_SIZE;
encryptor.processBlock(input, blockOffset, output, IV_SIZE + blockOffset);
}
// The IV locates on the first block of ciphertext
System.arraycopy(iv, 0, output, 0, BLOCK_SIZE);
return output;
}
public static byte getAESPadding(int dataLength) {
return (byte) (16 - dataLength % BLOCK_SIZE);
}
/**
* 计算密文长度(包括填充);<br>
*
......@@ -218,8 +227,9 @@ public class AESUtils {
decryptor.init(false, new ParametersWithIV(new KeyParameter(secretKey), iv));
byte[] outputWithPadding = new byte[length - BLOCK_SIZE];
// To decrypt the input in CBC mode
for (int i = 1; i < length / BLOCK_SIZE; i++) {
decryptor.processBlock(cipherBytes, i * BLOCK_SIZE, outputWithPadding, (i - 1) * BLOCK_SIZE);
int blockcount = length / BLOCK_SIZE;
for (int i = 1; i < blockcount; i++) {
decryptor.processBlock(cipherBytes, offset + i * BLOCK_SIZE, outputWithPadding, (i - 1) * BLOCK_SIZE);
}
int p = outputWithPadding[outputWithPadding.length - 1];
......
package utils.crypto.classic;
import org.bouncycastle.crypto.InvalidCipherTextException;
/**
* PKCS7 填充:
* <p>
*
* 假设块大小为 C ,目标数组需要填充 n 个字节后长度才能对其到整块,那么填充的 n 个字节每个的值都是 n;<br>
* 如果目标数据本身已经对齐了,则填充一个完整的块长度的数据,填充的 C 个字节每个的值都是 C;
*/
public class PKCS7PaddingUtils {
/**
* 向目标数组填充;
*
* @param target 要填充的数组;
* @param paddingOffset 填充的起始位置;
* @param paddingCode 填充值;同时,也是填充的字节长度;
* @return
*/
public static int addPadding(byte[] target, int paddingOffset, byte paddingCode) {
int i = 0;
while (i < paddingCode) {
target[paddingOffset + i] = paddingCode;
i++;
}
return paddingCode;
}
/**
* return the number of pad bytes present in the block.
*/
public int padCount(byte[] in) throws InvalidCipherTextException {
int count = in[in.length - 1] & 0xff;
byte countAsbyte = (byte) count;
// constant time version
boolean failed = (count > in.length | count == 0);
for (int i = 0; i < in.length; i++) {
failed |= (in.length - i <= count) & (in[i] != countAsbyte);
}
if (failed) {
throw new InvalidCipherTextException("pad block corrupted");
}
return count;
}
}
\ No newline at end of file
......@@ -19,81 +19,89 @@ import static org.junit.Assert.assertEquals;
*/
public class AESUtilsTest {
@Test
public void generateKeyTest(){
byte[] key = AESUtils.generateKey();
assertEquals(16,key.length);
key = AESUtils.generateKey(BytesUtils.toBytes("abc"));
assertArrayEquals(
Hex.decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad".substring(0,32)),key);
}
@Test
public void encryptTest(){
String plaintext = "abc";
String key = "1234567890123456";
String iv = "1234567890123456";
String expectedCiphertextIn2ndBlock = "f479efae2d41d23227f61e675fced95c";
byte[] ciphertext = AESUtils.encrypt(BytesUtils.toBytes(plaintext),
BytesUtils.toBytes(key), BytesUtils.toBytes(iv));
byte[] expectedCiphertext = BytesUtils.concat(BytesUtils.toBytes(iv),Hex.decode(expectedCiphertextIn2ndBlock));
assertArrayEquals(expectedCiphertext,ciphertext);
}
@Test
public void decryptTest(){
Random random = new Random();
byte[] data = new byte[1024];
random.nextBytes(data);
byte[] key = AESUtils.generateKey();
byte[] ciphertext = AESUtils.encrypt(data,key);
byte[] plaintext = AESUtils.decrypt(ciphertext,key);
assertArrayEquals(data,plaintext);
}
public void encryptingPerformance() {
byte[] data = new byte[1000];
Random random = new Random();
random.nextBytes(data);
byte[] aesCiphertext = null;
int count = 100000;
byte[] aesKey = AESUtils.generateKey();
System.out.println("=================== do AES encrypt test ===================");
for (int r = 0; r < 5; r++) {
System.out.println("------------- round[" + r + "] --------------");
long startTS = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
aesCiphertext = AESUtils.encrypt(data, aesKey);
}
long elapsedTS = System.currentTimeMillis() - startTS;
System.out.println(String.format("AES Encrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS,
(count * 1000.00D) / elapsedTS));
}
System.out.println("=================== do AES decrypt test ===================");
for (int r = 0; r < 5; r++) {
System.out.println("------------- round[" + r + "] --------------");
long startTS = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
AESUtils.decrypt(aesCiphertext, aesKey);
}
long elapsedTS = System.currentTimeMillis() - startTS;
System.out.println(String.format("AES Decrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS,
(count * 1000.00D) / elapsedTS));
}
}
@Test
public void generateKeyTest() {
byte[] key = AESUtils.generateKey();
assertEquals(16, key.length);
key = AESUtils.generateKey(BytesUtils.toBytes("abc"));
assertArrayEquals(
Hex.decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad".substring(0, 32)), key);
}
@Test
public void encryptTest() {
String plaintext = "abc";
String key = "1234567890123456";
String iv = "1234567890123456";
String expectedCiphertextIn2ndBlock = "f479efae2d41d23227f61e675fced95c";
byte[] ciphertext = AESUtils.encrypt(BytesUtils.toBytes(plaintext), BytesUtils.toBytes(key),
BytesUtils.toBytes(iv));
byte[] expectedCiphertext = BytesUtils.concat(BytesUtils.toBytes(iv), Hex.decode(expectedCiphertextIn2ndBlock));
assertArrayEquals(expectedCiphertext, ciphertext);
}
@Test
public void decryptTest() {
Random random = new Random();
byte[] data = new byte[171];
random.nextBytes(data);
byte[] key = AESUtils.generateKey();
byte[] cipherbytes = AESUtils.encrypt(data, key);
byte[] plainbytes = AESUtils.decrypt(cipherbytes, key);
assertArrayEquals(data, plainbytes);
// 验证待偏移量参数的解密方法;
byte[] complexBytes = BytesUtils.concat(data, cipherbytes);
plainbytes = AESUtils.decrypt(complexBytes, data.length, cipherbytes.length, key);
assertArrayEquals(data, plainbytes);
byte[] data2 = new byte[688];
random.nextBytes(data2);
complexBytes = BytesUtils.concat(data, data2);
cipherbytes = AESUtils.encrypt(complexBytes, data.length, data2.length, key);
plainbytes = AESUtils.decrypt(cipherbytes, key);
assertArrayEquals(data2, plainbytes);
}
public void encryptingPerformance() {
byte[] data = new byte[1000];
Random random = new Random();
random.nextBytes(data);
byte[] aesCiphertext = null;
int count = 100000;
byte[] aesKey = AESUtils.generateKey();
System.out.println("=================== do AES encrypt test ===================");
for (int r = 0; r < 5; r++) {
System.out.println("------------- round[" + r + "] --------------");
long startTS = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
aesCiphertext = AESUtils.encrypt(data, aesKey);
}
long elapsedTS = System.currentTimeMillis() - startTS;
System.out.println(String.format("AES Encrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS,
(count * 1000.00D) / elapsedTS));
}
System.out.println("=================== do AES decrypt test ===================");
for (int r = 0; r < 5; r++) {
System.out.println("------------- round[" + r + "] --------------");
long startTS = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
AESUtils.decrypt(aesCiphertext, aesKey);
}
long elapsedTS = System.currentTimeMillis() - startTS;
System.out.println(String.format("AES Decrypting Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS,
(count * 1000.00D) / elapsedTS));
}
}
}
......@@ -5,7 +5,7 @@
<parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
</parent>
<artifactId>utils-crypto-sm</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
</parent>
<artifactId>utils-serialize</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
</parent>
<artifactId>utils-test</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.jd.utils</groupId>
<artifactId>utils</artifactId>
<version>2.1.0-SNAPSHOT</version>
<version>2.0.3.RELEASE</version>
</parent>
<artifactId>utils-web-server</artifactId>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册