Skip to content

Commit b587868

Browse files
authored
Merge pull request #6 from imabhichow/main
Add RSA/ECB Legacy Keyring
2 parents 4fb7793 + 74827aa commit b587868

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package software.amazon.encryption.s3.legacy.materials;
2+
3+
4+
import software.amazon.encryption.s3.S3EncryptionClientException;
5+
import software.amazon.encryption.s3.materials.DecryptionMaterials;
6+
import software.amazon.encryption.s3.materials.EncryptedDataKey;
7+
import software.amazon.encryption.s3.materials.EncryptionMaterials;
8+
import software.amazon.encryption.s3.materials.Keyring;
9+
10+
import javax.crypto.Cipher;
11+
import java.security.Key;
12+
import java.security.KeyPair;
13+
import java.util.List;
14+
15+
/**
16+
* RsaEcbKeyring is a legacy, decrypt-only keyring and will use an RSA Public key to unwrap the data key
17+
* used to encrypt content.
18+
*/
19+
20+
public class RsaEcbKeyring implements Keyring{
21+
22+
private static final String KEY_ALGORITHM = "RSA";
23+
private static final String KEY_PROVIDER_ID = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
24+
private static final String CIPHER_ALGORITHM = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
25+
26+
private final KeyPair _wrappingKeyPair;
27+
28+
private RsaEcbKeyring(RsaEcbKeyring.Builder builder) {
29+
_wrappingKeyPair = builder._wrappingKeyPair;
30+
}
31+
32+
public static RsaEcbKeyring.Builder builder() {
33+
return new RsaEcbKeyring.Builder();
34+
}
35+
36+
@Override
37+
public EncryptionMaterials onEncrypt(EncryptionMaterials materials) {
38+
throw new S3EncryptionClientException("Encrypt not supported for " + KEY_PROVIDER_ID);
39+
}
40+
41+
@Override
42+
public DecryptionMaterials onDecrypt(DecryptionMaterials materials, List<EncryptedDataKey> encryptedDataKeys) {
43+
if (materials.plaintextDataKey() != null) {
44+
throw new S3EncryptionClientException("Decryption materials already contains a plaintext data key.");
45+
}
46+
47+
for (EncryptedDataKey encryptedDataKey : encryptedDataKeys) {
48+
if (!encryptedDataKey.keyProviderId().equals(KEY_PROVIDER_ID)) {
49+
continue;
50+
}
51+
52+
try {
53+
final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
54+
cipher.init(Cipher.UNWRAP_MODE, _wrappingKeyPair.getPrivate());
55+
56+
Key plaintextKey = cipher.unwrap(encryptedDataKey.ciphertext(), CIPHER_ALGORITHM, Cipher.SECRET_KEY);
57+
58+
return materials.toBuilder().plaintextDataKey(plaintextKey.getEncoded()).build();
59+
} catch (Exception e) {
60+
throw new S3EncryptionClientException("Unable to " + KEY_PROVIDER_ID + " unwrap", e);
61+
}
62+
}
63+
64+
return materials;
65+
}
66+
67+
public static class Builder {
68+
private KeyPair _wrappingKeyPair;
69+
70+
private Builder() {}
71+
72+
public RsaEcbKeyring.Builder wrappingKeyPair(KeyPair wrappingKeyPair) {
73+
if (!wrappingKeyPair.getPublic().getAlgorithm().equals(KEY_ALGORITHM)) {
74+
throw new S3EncryptionClientException("Invalid algorithm '" + wrappingKeyPair.getPublic().getAlgorithm() + "', expecting " + KEY_ALGORITHM);
75+
}
76+
_wrappingKeyPair = wrappingKeyPair;
77+
return this;
78+
}
79+
80+
public RsaEcbKeyring build() {
81+
return new RsaEcbKeyring(this);
82+
}
83+
}
84+
}
85+
86+

0 commit comments

Comments
 (0)