Browse Source

fix wrong implementations of AESEncryptionFunction and SM4EncryptionFunction in stream encrypting/decrypting

tags/1.0.0
zhanglin33 6 years ago
parent
commit
08110bbc3f
2 changed files with 87 additions and 25 deletions
  1. +14
    -11
      source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/service/classic/AESEncryptionFunction.java
  2. +73
    -14
      source/crypto/crypto-sm/src/main/java/com/jd/blockchain/crypto/service/sm/SM4EncryptionFunction.java

+ 14
- 11
source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/service/classic/AESEncryptionFunction.java View File

@@ -21,6 +21,7 @@ public class AESEncryptionFunction implements SymmetricEncryptionFunction {
private static final int KEY_SIZE = 128 / 8;
private static final int BLOCK_SIZE = 128 / 8;

// AES-ECB
private static final int PLAINTEXT_BUFFER_LENGTH = 256;
private static final int CIPHERTEXT_BUFFER_LENGTH = 256 + 16 + 2;

@@ -52,7 +53,7 @@ public class AESEncryptionFunction implements SymmetricEncryptionFunction {
public void encrypt(SymmetricKey key, InputStream in, OutputStream out) {
// 读输入流得到明文,加密,密文数据写入输出流
try {
// TODO: 错误地使用 available 方法;

byte[] buffBytes = new byte[PLAINTEXT_BUFFER_LENGTH];

@@ -65,15 +66,16 @@ public class AESEncryptionFunction implements SymmetricEncryptionFunction {
int len;
int i;

while((len=in.read(buffBytes)) > 0){
while((len=in.read(buffBytes)) > 0) {
padding = (byte) (PLAINTEXT_BUFFER_LENGTH - len);
i = len;
while (i < plaintextWithPadding.length){
while (i < plaintextWithPadding.length) {
plaintextWithPadding[i] = padding;
i++;
}
out.write(encrypt(key,plaintextWithPadding).toBytes());
}
// // TODO: 错误地使用 available 方法;
// int size = in.available();
// if (size < 1){
// throw new CryptoException("The input is null!");
@@ -127,14 +129,14 @@ public class AESEncryptionFunction implements SymmetricEncryptionFunction {
// 读输入流得到密文数据,解密,明文写入输出流
try {
byte[] buffBytes = new byte[CIPHERTEXT_BUFFER_LENGTH];
byte[] plaintextWithPadding = new byte[PLAINTEXT_BUFFER_LENGTH + 1];
byte[] plaintextWithPadding;

byte padding;
byte[] plaintext;

int len,i;
while ((len = in.read(buffBytes)) > 0){
if (len != CIPHERTEXT_BUFFER_LENGTH){
while ((len = in.read(buffBytes)) > 0) {
if (len != CIPHERTEXT_BUFFER_LENGTH) {
throw new CryptoException("inputStream's length is wrong!");
}
if (!supportCiphertext(buffBytes)) {
@@ -143,17 +145,18 @@ public class AESEncryptionFunction implements SymmetricEncryptionFunction {

plaintextWithPadding = decrypt(key,resolveCiphertext(buffBytes));

if (plaintextWithPadding.length != (PLAINTEXT_BUFFER_LENGTH +1)){
throw new CryptoException("The decrypted plaintext is valid");
if (plaintextWithPadding.length != (PLAINTEXT_BUFFER_LENGTH + 1)) {
throw new CryptoException("The decrypted plaintext is invalid");
}


padding = plaintextWithPadding[PLAINTEXT_BUFFER_LENGTH];
i = PLAINTEXT_BUFFER_LENGTH;

while ((PLAINTEXT_BUFFER_LENGTH - padding) < i) {

while ((PLAINTEXT_BUFFER_LENGTH - padding) < i){

if (plaintextWithPadding[i] != padding) {
throw new CryptoException("The inputSteam padding is invalid!");
}
i--;
}
plaintext = new byte[PLAINTEXT_BUFFER_LENGTH - padding];


+ 73
- 14
source/crypto/crypto-sm/src/main/java/com/jd/blockchain/crypto/service/sm/SM4EncryptionFunction.java View File

@@ -20,6 +20,10 @@ public class SM4EncryptionFunction implements SymmetricEncryptionFunction {
private static final int KEY_SIZE = 128 / 8;
private static final int BLOCK_SIZE = 128 / 8;

// SM4-CBC
private static final int PLAINTEXT_BUFFER_LENGTH = 256;
private static final int CIPHERTEXT_BUFFER_LENGTH = 256 + 32 + 2;

private static final int SYMMETRICKEY_LENGTH = ALGORYTHM_CODE_SIZE + KEY_TYPE_BYTES + KEY_SIZE;

SM4EncryptionFunction() {
@@ -49,12 +53,32 @@ public class SM4EncryptionFunction implements SymmetricEncryptionFunction {

// 读输入流得到明文,加密,密文数据写入输出流
try {
byte[] sm4Data = new byte[in.available()];
in.read(sm4Data);
in.close();
byte[] buffBytes = new byte[PLAINTEXT_BUFFER_LENGTH];

// The final byte of plaintextWithPadding represents the length of padding in the first 256 bytes,
// and the padded value in hexadecimal
byte[] plaintextWithPadding = new byte[buffBytes.length + 1];

byte padding;

int len;
int i;

out.write(encrypt(key, sm4Data).toBytes());
out.close();
while((len=in.read(buffBytes)) > 0) {
padding = (byte) (PLAINTEXT_BUFFER_LENGTH - len);
i = len;
while (i < plaintextWithPadding.length) {
plaintextWithPadding[i] = padding;
i++;
}
out.write(encrypt(key,plaintextWithPadding).toBytes());
}
// byte[] sm4Data = new byte[in.available()];
// in.read(sm4Data);
// in.close();
//
// out.write(encrypt(key, sm4Data).toBytes());
// out.close();
} catch (IOException e) {
throw new CryptoException(e.getMessage(), e);
}
@@ -94,16 +118,51 @@ public class SM4EncryptionFunction implements SymmetricEncryptionFunction {
public void decrypt(SymmetricKey key, InputStream in, OutputStream out) {
// 读输入流得到密文数据,解密,明文写入输出流
try {
byte[] sm4Data = new byte[in.available()];
in.read(sm4Data);
in.close();

if (!supportCiphertext(sm4Data)) {
throw new CryptoException("InputStream is not valid SM4 ciphertext!");
byte[] buffBytes = new byte[CIPHERTEXT_BUFFER_LENGTH];
byte[] plaintextWithPadding;

byte padding;
byte[] plaintext;

int len,i;
while ((len = in.read(buffBytes)) > 0) {
if (len != CIPHERTEXT_BUFFER_LENGTH) {
throw new CryptoException("inputStream's length is wrong!");
}
if (!supportCiphertext(buffBytes)) {
throw new CryptoException("InputStream is not valid SM4 ciphertext!");
}

plaintextWithPadding = decrypt(key,resolveCiphertext(buffBytes));

if (plaintextWithPadding.length != (PLAINTEXT_BUFFER_LENGTH + 1)) {
throw new CryptoException("The decrypted plaintext is invalid");
}

padding = plaintextWithPadding[PLAINTEXT_BUFFER_LENGTH];
i = PLAINTEXT_BUFFER_LENGTH;

while ((PLAINTEXT_BUFFER_LENGTH - padding) < i) {

if (plaintextWithPadding[i] != padding) {
throw new CryptoException("The inputSteam padding is invalid!");
}
i--;
}
plaintext = new byte[PLAINTEXT_BUFFER_LENGTH - padding];
System.arraycopy(plaintextWithPadding,0,plaintext,0,plaintext.length);
out.write(plaintext);
}

out.write(decrypt(key, resolveCiphertext(sm4Data)));
out.close();
// byte[] sm4Data = new byte[in.available()];
// in.read(sm4Data);
// in.close();
//
// if (!supportCiphertext(sm4Data)) {
// throw new CryptoException("InputStream is not valid SM4 ciphertext!");
// }
//
// out.write(decrypt(key, resolveCiphertext(sm4Data)));
// out.close();
} catch (IOException e) {
throw new CryptoException(e.getMessage(), e);
}


Loading…
Cancel
Save