-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for encryption algorithms for symmetric keys #17209
Changes from 7 commits
2514dd1
c48a75a
7d030d0
67e837c
17b8e1b
37d0e65
059c29c
df0aeb7
596d98e
8b93751
b1f1511
ff77ba1
53c8771
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
package com.azure.security.keyvault.keys.cryptography; | ||
|
||
class Aes128CbcPad extends AesCbcPad { | ||
private static final int KEY_SIZE = 128; | ||
public static final String ALGORITHM_NAME = "A128CBCPAD"; | ||
|
||
Aes128CbcPad() { | ||
super(ALGORITHM_NAME, KEY_SIZE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
package com.azure.security.keyvault.keys.cryptography; | ||
|
||
class Aes128Gcm extends AesGcm { | ||
private static final int KEY_SIZE = 128; | ||
public static final String ALGORITHM_NAME = "A128GCM"; | ||
|
||
Aes128Gcm() { | ||
super(ALGORITHM_NAME, KEY_SIZE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
package com.azure.security.keyvault.keys.cryptography; | ||
|
||
class Aes192CbcPad extends AesCbcPad { | ||
private static final int KEY_SIZE = 192; | ||
public static final String ALGORITHM_NAME = "A192CBCPAD"; | ||
|
||
Aes192CbcPad() { | ||
super(ALGORITHM_NAME, KEY_SIZE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
package com.azure.security.keyvault.keys.cryptography; | ||
|
||
class Aes192Gcm extends AesGcm { | ||
private static final int KEY_SIZE = 192; | ||
public static final String ALGORITHM_NAME = "A192GCM"; | ||
|
||
Aes192Gcm() { | ||
super(ALGORITHM_NAME, KEY_SIZE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
package com.azure.security.keyvault.keys.cryptography; | ||
|
||
class Aes256CbcPad extends AesCbcPad { | ||
private static final int KEY_SIZE = 256; | ||
public static final String ALGORITHM_NAME = "A256CBCPAD"; | ||
|
||
Aes256CbcPad() { | ||
super(ALGORITHM_NAME, KEY_SIZE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
package com.azure.security.keyvault.keys.cryptography; | ||
|
||
class Aes256Gcm extends AesGcm { | ||
private static final int KEY_SIZE = 256; | ||
public static final String ALGORITHM_NAME = "A256GCM"; | ||
|
||
Aes256Gcm() { | ||
super(ALGORITHM_NAME, KEY_SIZE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
package com.azure.security.keyvault.keys.cryptography; | ||
|
||
import javax.crypto.BadPaddingException; | ||
import javax.crypto.Cipher; | ||
import javax.crypto.IllegalBlockSizeException; | ||
import javax.crypto.NoSuchPaddingException; | ||
import javax.crypto.spec.IvParameterSpec; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import java.security.InvalidAlgorithmParameterException; | ||
import java.security.InvalidKeyException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.Provider; | ||
import java.util.Arrays; | ||
|
||
abstract class AesCbcPad extends SymmetricEncryptionAlgorithm { | ||
final int keySizeInBytes; | ||
final int keySize; | ||
|
||
protected AesCbcPad(String name, int size) { | ||
super(name); | ||
|
||
keySize = size; | ||
keySizeInBytes = size >> 3; | ||
} | ||
|
||
static class AesCbcPadEncryptor implements ICryptoTransform { | ||
private final Cipher cipher; | ||
|
||
AesCbcPadEncryptor(byte[] key, byte[] iv, Provider provider) throws NoSuchAlgorithmException, | ||
NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { | ||
|
||
// Create the cipher using the Provider if specified | ||
if (provider == null) { | ||
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be PKCS7 padding, though for 8-byte block sizes this should be equivalent. If PKCS7 is supported, it may be safer for future proofing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In that case, it shouldn't matter. /cc @schaabs to confirm my understanding. |
||
} else { | ||
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", provider); | ||
} | ||
|
||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv)); | ||
} | ||
|
||
@Override | ||
public byte[] doFinal(byte[] plaintext) throws IllegalBlockSizeException, BadPaddingException { | ||
return cipher.doFinal(plaintext); | ||
} | ||
} | ||
|
||
static class AesCbcPadDecryptor implements ICryptoTransform { | ||
private final Cipher cipher; | ||
|
||
AesCbcPadDecryptor(byte[] key, byte[] iv, Provider provider) throws NoSuchAlgorithmException, | ||
NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { | ||
|
||
// Create the cipher using the Provider if specified | ||
if (provider == null) { | ||
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | ||
} else { | ||
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", provider); | ||
} | ||
|
||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv)); | ||
} | ||
|
||
@Override | ||
public byte[] doFinal(byte[] plaintext) throws IllegalBlockSizeException, BadPaddingException { | ||
return cipher.doFinal(plaintext); | ||
} | ||
} | ||
|
||
@Override | ||
public ICryptoTransform createEncryptor(byte[] key, byte[] iv, byte[] authenticationData) | ||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, | ||
InvalidAlgorithmParameterException { | ||
|
||
return createEncryptor(key, iv, authenticationData, null); | ||
} | ||
|
||
@Override | ||
public ICryptoTransform createEncryptor(byte[] key, byte[] iv, byte[] authenticationData, Provider provider) | ||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, | ||
InvalidAlgorithmParameterException { | ||
|
||
if (key == null || key.length < keySizeInBytes) { | ||
throw new InvalidKeyException("key must be at least " + keySize + " bits in length"); | ||
} | ||
|
||
return new AesCbcPadEncryptor(Arrays.copyOfRange(key, 0, keySizeInBytes), iv, provider); | ||
} | ||
|
||
@Override | ||
public ICryptoTransform createDecryptor(byte[] key, byte[] iv, byte[] authenticationData, byte[] authenticationTag) | ||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, | ||
InvalidAlgorithmParameterException { | ||
|
||
return createDecryptor(key, iv, authenticationData, authenticationTag, null); | ||
} | ||
|
||
@Override | ||
public ICryptoTransform createDecryptor(byte[] key, byte[] iv, byte[] authenticationData, byte[] authenticationTag, | ||
Provider provider) | ||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, | ||
InvalidAlgorithmParameterException { | ||
|
||
if (key == null || key.length < keySizeInBytes) { | ||
throw new InvalidKeyException("key must be at least " + keySize + " bits in length"); | ||
} | ||
|
||
return new AesCbcPadDecryptor(Arrays.copyOfRange(key, 0, keySizeInBytes), iv, provider); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lusitanian should this be zero-padding? When we spoke about .NET, you said zero-padding was what the service was using.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...if this is right, I'll have to change .NET's implementation to NoPadding as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going from the name only it made sense to me that we should not use padding for AES-CBC and use padding for AES-CBC-PAD. Is that not the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I asked MHSM about it, the reply was that zero-padding seems to be closer. I'm honestly not sure. If you're writing tests, maybe try it against the service and see what it does with CBC vs CBCPAD.