Skip to content

Commit ebe0364

Browse files
author
aldoli
committed
add new encryption mode aes cbc
1 parent f1922c7 commit ebe0364

13 files changed

+173
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [5.6.56]
9+
- add encryption mode aes cbc
10+
811
## [5.6.55]
912
- add batch image auditing api
1013
- add DocumentAuditing api

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.qcloud</groupId>
66
<artifactId>cos_api</artifactId>
7-
<version>5.6.55</version>
7+
<version>5.6.56</version>
88
<packaging>jar</packaging>
99
<name>cos-java-sdk</name>
1010
<description>java sdk for qcloud cos</description>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
15+
* According to cos feature, we modify some class,comment, field name, etc.
16+
*/
17+
18+
package com.qcloud.cos.internal.crypto;
19+
20+
class AesCbc extends ContentCryptoScheme {
21+
22+
private byte[] iv = null;
23+
24+
@Override String getKeyGeneratorAlgorithm() { return AES_GCM.getKeyGeneratorAlgorithm(); }
25+
@Override String getCipherAlgorithm() { return "AES/CBC/PKCS5Padding"; }
26+
@Override int getKeyLengthInBits() { return AES_GCM.getKeyLengthInBits(); }
27+
@Override int getBlockSizeInBytes() { return AES_GCM.getBlockSizeInBytes(); }
28+
@Override int getIVLengthInBytes() { return 16; }
29+
@Override long getMaxPlaintextSize() { return MAX_CTR_BYTES; }
30+
@Override byte[] getIV() { return this.iv; }
31+
32+
@Override
33+
byte[] adjustIV(byte[] iv, long byteOffset) {
34+
// currently only support iv of length 12 for AES/GCM.
35+
// Anything else is quite a bit complicated.
36+
if (iv.length != 12)
37+
throw new UnsupportedOperationException();
38+
final int blockSize = getBlockSizeInBytes();
39+
final long blockOffset = byteOffset / blockSize;
40+
if (blockOffset * blockSize != byteOffset) {
41+
throw new IllegalArgumentException(
42+
"Expecting byteOffset to be multiple of 16, but got blockOffset="
43+
+ blockOffset + ", blockSize=" + blockSize
44+
+ ", byteOffset=" + byteOffset);
45+
}
46+
byte[] J0 = computeJ0(iv);
47+
return incrementBlocks(J0, blockOffset);
48+
}
49+
50+
@Override
51+
public void setIV(byte[] iv) {
52+
this.iv = iv;
53+
}
54+
55+
private byte[] computeJ0(byte[] nonce) {
56+
final int blockSize = getBlockSizeInBytes();
57+
byte[] J0 = new byte[blockSize];
58+
System.arraycopy(nonce, 0, J0, 0, nonce.length);
59+
J0[blockSize - 1] = 0x01;
60+
return incrementBlocks(J0, 1);
61+
}
62+
}

src/main/java/com/qcloud/cos/internal/crypto/AesCtr.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
package com.qcloud.cos.internal.crypto;
2020

2121
class AesCtr extends ContentCryptoScheme {
22+
2223
@Override String getKeyGeneratorAlgorithm() { return AES_GCM.getKeyGeneratorAlgorithm(); }
2324
@Override String getCipherAlgorithm() { return "AES/CTR/NoPadding"; }
2425
@Override int getKeyLengthInBits() { return AES_GCM.getKeyLengthInBits(); }
2526
@Override int getBlockSizeInBytes() { return AES_GCM.getBlockSizeInBytes(); }
2627
@Override int getIVLengthInBytes() { return 16; }
2728
@Override long getMaxPlaintextSize() { return MAX_CTR_BYTES; }
29+
@Override byte[] getIV() { return null; }
30+
@Override void setIV(byte[] iv) {}
2831

2932
@Override
3033
byte[] adjustIV(byte[] iv, long byteOffset) {
@@ -44,11 +47,12 @@ byte[] adjustIV(byte[] iv, long byteOffset) {
4447
return incrementBlocks(J0, blockOffset);
4548
}
4649

47-
private byte[] computeJ0(byte[] nonce) {
48-
final int blockSize = getBlockSizeInBytes();
49-
byte[] J0 = new byte[blockSize];
50-
System.arraycopy(nonce, 0, J0, 0, nonce.length);
51-
J0[blockSize - 1] = 0x01;
52-
return incrementBlocks(J0, 1);
53-
}
50+
private byte[] computeJ0(byte[] nonce) {
51+
final int blockSize = getBlockSizeInBytes();
52+
byte[] J0 = new byte[blockSize];
53+
System.arraycopy(nonce, 0, J0, 0, nonce.length);
54+
J0[blockSize - 1] = 0x01;
55+
return incrementBlocks(J0, 1);
56+
}
57+
5458
}

src/main/java/com/qcloud/cos/internal/crypto/AesGcm.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class AesGcm extends ContentCryptoScheme {
3535
@Override int getBlockSizeInBytes() { return 16; }
3636
@Override int getIVLengthInBytes() { return 12; }
3737
@Override long getMaxPlaintextSize() { return MAX_GCM_BYTES; }
38+
@Override byte[] getIV() { return null; }
39+
@Override void setIV(byte[] iv) {}
40+
3841
/**
3942
* Used to explicitly record the tag length in COS for interoperability
4043
* with other services.
@@ -60,4 +63,5 @@ CipherLite createAuxillaryCipher(SecretKey cek, byte[] ivOrig,
6063
protected CipherLite newCipherLite(Cipher cipher, SecretKey cek, int cipherMode) {
6164
return new GCMCipherLite(cipher, cek, cipherMode);
6265
}
66+
6367
}

src/main/java/com/qcloud/cos/internal/crypto/COSCryptoModuleAE.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ private void assertParameterNotNull(Object parameterValue, String errorMessage)
350350
}
351351

352352
@Override
353-
protected final long ciphertextLength(long originalContentLength) {
353+
protected long ciphertextLength(long originalContentLength) {
354354
// Add 16 bytes for the 128-bit tag length using AES/GCM
355355
return originalContentLength + contentCryptoScheme.getTagLengthInBits() / 8;
356356
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
15+
* According to cos feature, we modify some class,comment, field name, etc.
16+
*/
17+
18+
19+
package com.qcloud.cos.internal.crypto;
20+
21+
import com.qcloud.cos.auth.COSCredentialsProvider;
22+
import com.qcloud.cos.internal.COSDirect;
23+
24+
public class COSCryptoModuleAECbc extends COSCryptoModuleAE {
25+
26+
public COSCryptoModuleAECbc(COSDirect cos, COSCredentialsProvider credentialsProvider,
27+
EncryptionMaterialsProvider kekMaterialsProvider, CryptoConfiguration cryptoConfig) {
28+
this(null, cos, credentialsProvider, kekMaterialsProvider, cryptoConfig);
29+
}
30+
31+
public COSCryptoModuleAECbc(QCLOUDKMS kms, COSDirect cos,
32+
COSCredentialsProvider credentialsProvider,
33+
EncryptionMaterialsProvider kekMaterialsProvider, CryptoConfiguration cryptoConfig) {
34+
super(kms, cos, credentialsProvider, kekMaterialsProvider, cryptoConfig);
35+
}
36+
37+
protected long ciphertextLength(long originalContentLength) {
38+
return originalContentLength + 16 - originalContentLength % 16;
39+
}
40+
}

src/main/java/com/qcloud/cos/internal/crypto/COSCryptoModuleBase.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ protected COSCryptoModuleBase(QCLOUDKMS kms, COSDirect cos,
117117
this.cryptoScheme = COSCryptoScheme.from(cryptoConfig.getCryptoMode());
118118
this.contentCryptoScheme = cryptoScheme.getContentCryptoScheme();
119119
this.kms = kms;
120+
121+
// if have user defined iv, set it to contentCryptoScheme.
122+
this.contentCryptoScheme.setIV(cryptoConfig.getIV());
120123
}
121124

122125
/**
@@ -467,9 +470,13 @@ private ContentCryptoMaterial newContentCryptoMaterial(
467470
*/
468471
private ContentCryptoMaterial buildContentCryptoMaterial(EncryptionMaterials materials,
469472
Provider provider, CosServiceRequest req) {
470-
// Randomly generate the IV
471-
final byte[] iv = new byte[contentCryptoScheme.getIVLengthInBytes()];
472-
cryptoScheme.getSecureRandom().nextBytes(iv);
473+
byte[] iv = contentCryptoScheme.getIV();
474+
475+
if (iv == null) {
476+
// Randomly generate the IV
477+
iv = new byte[contentCryptoScheme.getIVLengthInBytes()];
478+
cryptoScheme.getSecureRandom().nextBytes(iv);
479+
}
473480

474481
if (materials.isKMSEnabled()) {
475482
final Map<String, String> encryptionContext =
@@ -569,7 +576,6 @@ protected final <R extends AbstractPutObjectRequest> R wrapWithCipher(final R re
569576
if (plaintextLength >= 0) {
570577
metadata.addUserMetadata(Headers.ENCRYPTION_UNENCRYPTED_CONTENT_LENGTH,
571578
Long.toString(plaintextLength));
572-
// Put the ciphertext length in the metadata
573579
metadata.setContentLength(ciphertextLength(plaintextLength));
574580
}
575581
request.setMetadata(metadata);

src/main/java/com/qcloud/cos/internal/crypto/COSCryptoScheme.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ static boolean isAesGcm(String cipherAlgorithm) {
5555

5656
static COSCryptoScheme from(CryptoMode mode) {
5757
switch (mode) {
58+
case AesCbcEncryption:
59+
return new COSCryptoScheme(ContentCryptoScheme.AES_CBC,
60+
new COSKeyWrapScheme());
5861
case AesCtrEncryption:
5962
return new COSCryptoScheme(ContentCryptoScheme.AES_CTR,
6063
new COSKeyWrapScheme());

src/main/java/com/qcloud/cos/internal/crypto/ContentCryptoScheme.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ abstract class ContentCryptoScheme {
7070
*/
7171
static final ContentCryptoScheme AES_CTR = new AesCtr();
7272

73+
/**
74+
* Crypto scheme "AES/CBC/PKCS5Padding"
75+
*/
76+
static final ContentCryptoScheme AES_CBC = new AesCbc();
77+
7378
abstract String getKeyGeneratorAlgorithm();
7479
abstract String getCipherAlgorithm();
7580

@@ -82,6 +87,8 @@ abstract class ContentCryptoScheme {
8287
abstract int getKeyLengthInBits();
8388
abstract int getBlockSizeInBytes();
8489
abstract int getIVLengthInBytes();
90+
abstract byte[] getIV();
91+
abstract void setIV(byte[] iv);
8592

8693
int getTagLengthInBits() { return 0; } // default to zero ie no tag
8794

@@ -152,6 +159,10 @@ static ContentCryptoScheme fromCEKAlgo(String cekAlgo, boolean isRangeGet) {
152159
return AES_CTR;
153160
}
154161

162+
if (AES_CBC.getCipherAlgorithm().equals(cekAlgo)) {
163+
return AES_CBC;
164+
}
165+
155166
throw new UnsupportedOperationException("Unsupported content encryption scheme: " + cekAlgo);
156167
}
157168

0 commit comments

Comments
 (0)