32
32
import com .google .api .services .cloudkms .v1 .model .ListKeyRingsResponse ;
33
33
import java .io .IOException ;
34
34
import java .io .StringReader ;
35
- import java .nio .charset .StandardCharsets ;
36
35
import java .security .InvalidKeyException ;
37
36
import java .security .KeyFactory ;
38
37
import java .security .MessageDigest ;
43
42
import java .security .Signature ;
44
43
import java .security .SignatureException ;
45
44
import java .security .spec .InvalidKeySpecException ;
46
- import java .security .spec .PKCS8EncodedKeySpec ;
47
45
import java .security .spec .X509EncodedKeySpec ;
48
46
import java .util .Base64 ;
49
47
import javax .crypto .BadPaddingException ;
57
55
public class Asymmetric {
58
56
59
57
// [START kms_get_asymmetric_public]
60
- /** Retrieves the public key from a saved asymmetric key pair on Cloud KMS */
58
+ /**
59
+ * Retrieves the public key from a saved asymmetric key pair on Cloud KMS
60
+ *
61
+ * Requires:
62
+ * java.io.StringReader
63
+ * java.security.KeyFactory
64
+ * java.security.PublicKey
65
+ * java.security.Security
66
+ * java.security.spec.X509EncodedKeySpec
67
+ * org.bouncycastle.jce.provider.BouncyCastleProvider
68
+ * org.bouncycastle.util.io.pem.PemReader
69
+ */
61
70
public static PublicKey getAsymmetricPublicKey (CloudKMS client , String keyPath )
62
71
throws IOException , NoSuchAlgorithmException , InvalidKeySpecException ,
63
72
NoSuchProviderException {
@@ -86,26 +95,32 @@ public static PublicKey getAsymmetricPublicKey(CloudKMS client, String keyPath)
86
95
* Decrypt a given ciphertext using an 'RSA_DECRYPT_OAEP_2048_SHA256' private key
87
96
* stored on Cloud KMS
88
97
*/
89
- public static String decryptRSA (String ciphertext , CloudKMS client , String keyPath )
98
+ public static byte [] decryptRSA (byte [] ciphertext , CloudKMS client , String keyPath )
90
99
throws IOException {
91
- AsymmetricDecryptRequest request = new AsymmetricDecryptRequest ().setCiphertext (ciphertext );
100
+ AsymmetricDecryptRequest request = new AsymmetricDecryptRequest ().encodeCiphertext (ciphertext );
92
101
AsymmetricDecryptResponse response = client .projects ()
93
102
.locations ()
94
103
.keyRings ()
95
104
.cryptoKeys ()
96
105
.cryptoKeyVersions ()
97
106
.asymmetricDecrypt (keyPath , request )
98
107
.execute ();
99
- return new String ( response .decodePlaintext () );
108
+ return response .decodePlaintext ();
100
109
}
101
110
// [END kms_decrypt_rsa]
102
111
103
112
// [START kms_encrypt_rsa]
104
113
/**
105
- * Encrypt message locally using an 'RSA_DECRYPT_OAEP_2048_SHA256' public key
106
- * retrieved from Cloud KMS
114
+ * Encrypt data locally using an 'RSA_DECRYPT_OAEP_2048_SHA256' public key
115
+ * retrieved from Cloud KMS
116
+ *
117
+ * Requires:
118
+ * java.security.PublicKey
119
+ * java.security.Security
120
+ * javax.crypto.Cipher
121
+ * org.bouncycastle.jce.provider.BouncyCastleProvider
107
122
*/
108
- public static String encryptRSA (String message , CloudKMS client , String keyPath )
123
+ public static byte [] encryptRSA (byte [] plaintext , CloudKMS client , String keyPath )
109
124
throws IOException , IllegalBlockSizeException , NoSuchPaddingException ,
110
125
InvalidKeySpecException , NoSuchProviderException , BadPaddingException ,
111
126
NoSuchAlgorithmException , InvalidKeyException {
@@ -114,20 +129,23 @@ public static String encryptRSA(String message, CloudKMS client, String keyPath)
114
129
115
130
Cipher cipher = Cipher .getInstance ("RSA/NONE/OAEPWITHSHA256ANDMGF1PADDING" , "BC" );
116
131
cipher .init (Cipher .ENCRYPT_MODE , rsaKey );
117
- byte [] ciphertext = cipher .doFinal (message .getBytes (StandardCharsets .UTF_8 ));
118
- return Base64 .getEncoder ().encodeToString (ciphertext );
132
+ return cipher .doFinal (plaintext );
119
133
}
120
134
// [END kms_encrypt_rsa]
121
135
122
136
// [START kms_sign_asymmetric]
123
- /** Create a signature for a message using a private key stored on Cloud KMS */
124
- public static String signAsymmetric (String message , CloudKMS client , String keyPath )
137
+ /** Create a signature for a message using a private key stored on Cloud KMS
138
+ *
139
+ * Requires:
140
+ * java.security.MessageDigest
141
+ * java.util.Base64
142
+ */
143
+ public static byte [] signAsymmetric (byte [] message , CloudKMS client , String keyPath )
125
144
throws IOException , NoSuchAlgorithmException {
126
- byte [] msgBytes = message .getBytes (StandardCharsets .UTF_8 );
127
145
Digest digest = new Digest ();
128
146
// Note: some key algorithms will require a different hash function
129
147
// For example, EC_SIGN_P384_SHA384 requires SHA-384
130
- digest .encodeSha256 (MessageDigest .getInstance ("SHA-256" ).digest (msgBytes ));
148
+ digest .encodeSha256 (MessageDigest .getInstance ("SHA-256" ).digest (message ));
131
149
132
150
AsymmetricSignRequest signRequest = new AsymmetricSignRequest ();
133
151
signRequest .setDigest (digest );
@@ -139,16 +157,22 @@ public static String signAsymmetric(String message, CloudKMS client, String keyP
139
157
.cryptoKeyVersions ()
140
158
.asymmetricSign (keyPath , signRequest )
141
159
.execute ();
142
- return response .getSignature ();
160
+ return Base64 . getMimeDecoder (). decode ( response .getSignature () );
143
161
}
144
162
// [END kms_sign_asymmetric]
145
163
146
164
// [START kms_verify_signature_rsa]
147
165
/**
148
166
* Verify the validity of an 'RSA_SIGN_PSS_2048_SHA256' signature for the
149
- * specified plaintext message
167
+ * specified message
168
+ *
169
+ * Requires:
170
+ * java.security.PublicKey
171
+ * java.security.Security
172
+ * java.security.Signature
173
+ * org.bouncycastle.jce.provider.BouncyCastleProvider
150
174
*/
151
- public static boolean verifySignatureRSA (String signature , String message , CloudKMS client ,
175
+ public static boolean verifySignatureRSA (byte [] signature , byte [] message , CloudKMS client ,
152
176
String keyPath ) throws IOException , NoSuchAlgorithmException , InvalidKeySpecException ,
153
177
SignatureException , NoSuchProviderException , InvalidKeyException {
154
178
Security .addProvider (new BouncyCastleProvider ());
@@ -157,18 +181,23 @@ public static boolean verifySignatureRSA(String signature, String message, Cloud
157
181
Signature rsaVerify = Signature .getInstance ("SHA256withRSA/PSS" );
158
182
159
183
rsaVerify .initVerify (rsaKey );
160
- rsaVerify .update (message .getBytes (StandardCharsets .UTF_8 ));
161
- byte [] sigBytes = Base64 .getMimeDecoder ().decode (signature );
162
- return rsaVerify .verify (sigBytes );
184
+ rsaVerify .update (message );
185
+ return rsaVerify .verify (signature );
163
186
}
164
187
// [END kms_verify_signature_rsa]
165
188
166
189
// [START kms_verify_signature_ec]
167
190
/**
168
191
* Verify the validity of an 'EC_SIGN_P256_SHA256' signature for the
169
- * specified plaintext message
192
+ * specified message
193
+ *
194
+ * Requires:
195
+ * java.security.PublicKey
196
+ * java.security.Security
197
+ * java.security.Signature
198
+ * org.bouncycastle.jce.provider.BouncyCastleProvider
170
199
*/
171
- public static boolean verifySignatureEC (String signature , String message , CloudKMS client ,
200
+ public static boolean verifySignatureEC (byte [] signature , byte [] message , CloudKMS client ,
172
201
String keyPath ) throws IOException , NoSuchAlgorithmException , InvalidKeySpecException ,
173
202
SignatureException , NoSuchProviderException , InvalidKeyException {
174
203
Security .addProvider (new BouncyCastleProvider ());
@@ -177,9 +206,8 @@ public static boolean verifySignatureEC(String signature, String message, CloudK
177
206
Signature ecVerify = Signature .getInstance ("SHA256withECDSA" , "BC" );
178
207
179
208
ecVerify .initVerify (ecKey );
180
- ecVerify .update (message .getBytes (StandardCharsets .UTF_8 ));
181
- byte [] sigBytes = Base64 .getMimeDecoder ().decode (signature );
182
- return ecVerify .verify (sigBytes );
209
+ ecVerify .update (message );
210
+ return ecVerify .verify (signature );
183
211
}
184
212
// [END kms_verify_signature_ec]
185
213
0 commit comments