@@ -100,6 +100,33 @@ interface CtrComputer {
100
100
byte [] computeCtr (byte [] input , byte [] key , final byte [] iv );
101
101
}
102
102
103
+ /**
104
+ * Convenience method using a single 256, 384, or 512 bits key. This is just a wrapper for {@link #encrypt(byte[], byte[], byte[], byte[]...)}.
105
+ * @param key Combined key, which is split in half.
106
+ * @param plaintext Your plaintext, which shall be encrypted.
107
+ * @param associatedData Optional associated data, which gets authenticated but not encrypted.
108
+ * @return IV + Ciphertext as a concatenated byte array.
109
+ */
110
+ public byte [] encrypt (SecretKey key , byte [] plaintext , byte []... associatedData ) {
111
+ final byte [] keyBytes = key .getEncoded ();
112
+ if (keyBytes .length != 64 && keyBytes .length != 48 && keyBytes .length != 32 ) {
113
+ throw new IllegalArgumentException ("Key length must be 256, 384, or 512 bits." );
114
+ }
115
+ final int subkeyLen = keyBytes .length / 2 ;
116
+ assert subkeyLen == 32 || subkeyLen == 24 || subkeyLen == 16 ;
117
+ final byte [] macKey = new byte [subkeyLen ];
118
+ final byte [] ctrKey = new byte [subkeyLen ];
119
+ try {
120
+ System .arraycopy (keyBytes , 0 , macKey , 0 , macKey .length ); // K1 = leftmost(K, len(K)/2);
121
+ System .arraycopy (keyBytes , macKey .length , ctrKey , 0 , ctrKey .length ); // K2 = rightmost(K, len(K)/2);
122
+ return encrypt (ctrKey , macKey , plaintext , associatedData );
123
+ } finally {
124
+ Arrays .fill (macKey , (byte ) 0 );
125
+ Arrays .fill (ctrKey , (byte ) 0 );
126
+ Arrays .fill (keyBytes , (byte ) 0 );
127
+ }
128
+ }
129
+
103
130
/**
104
131
* Convenience method, if you are using the javax.crypto API. This is just a wrapper for {@link #encrypt(byte[], byte[], byte[], byte[]...)}.
105
132
*
@@ -150,6 +177,36 @@ public byte[] encrypt(byte[] ctrKey, byte[] macKey, byte[] plaintext, byte[]...
150
177
return result ;
151
178
}
152
179
180
+ /**
181
+ * Convenience method using a single 256, 384, or 512 bits key. This is just a wrapper for {@link #decrypt(byte[], byte[], byte[], byte[]...)}.
182
+ * @param key Combined key, which is split in half.
183
+ * @param ciphertext Your cipehrtext, which shall be decrypted.
184
+ * @param associatedData Optional associated data, which gets authenticated but not encrypted.
185
+ * @return Plaintext byte array.
186
+ * @throws IllegalArgumentException If keys are invalid.
187
+ * @throws UnauthenticCiphertextException If the authentication failed, e.g. because ciphertext and/or associatedData are corrupted.
188
+ * @throws IllegalBlockSizeException If the provided ciphertext is of invalid length.
189
+ */
190
+ public byte [] decrypt (SecretKey key , byte [] ciphertext , byte []... associatedData ) throws UnauthenticCiphertextException , IllegalBlockSizeException {
191
+ final byte [] keyBytes = key .getEncoded ();
192
+ if (keyBytes .length != 64 && keyBytes .length != 48 && keyBytes .length != 32 ) {
193
+ throw new IllegalArgumentException ("Key length must be 256, 384, or 512 bits." );
194
+ }
195
+ final int subkeyLen = keyBytes .length / 2 ;
196
+ assert subkeyLen == 32 || subkeyLen == 24 || subkeyLen == 16 ;
197
+ final byte [] macKey = new byte [subkeyLen ];
198
+ final byte [] ctrKey = new byte [subkeyLen ];
199
+ try {
200
+ System .arraycopy (keyBytes , 0 , macKey , 0 , macKey .length ); // K1 = leftmost(K, len(K)/2);
201
+ System .arraycopy (keyBytes , macKey .length , ctrKey , 0 , ctrKey .length ); // K2 = rightmost(K, len(K)/2);
202
+ return decrypt (ctrKey , macKey , ciphertext , associatedData );
203
+ } finally {
204
+ Arrays .fill (macKey , (byte ) 0 );
205
+ Arrays .fill (ctrKey , (byte ) 0 );
206
+ Arrays .fill (keyBytes , (byte ) 0 );
207
+ }
208
+ }
209
+
153
210
/**
154
211
* Convenience method, if you are using the javax.crypto API. This is just a wrapper for {@link #decrypt(byte[], byte[], byte[], byte[]...)}.
155
212
*
0 commit comments