1 /*
2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import static java.lang.System.out;
25 
26 import java.security.InvalidAlgorithmParameterException;
27 import java.security.InvalidKeyException;
28 import java.security.NoSuchAlgorithmException;
29 import java.security.spec.AlgorithmParameterSpec;
30 import java.security.spec.InvalidKeySpecException;
31 import java.util.Arrays;
32 
33 import javax.crypto.BadPaddingException;
34 import javax.crypto.Cipher;
35 import javax.crypto.IllegalBlockSizeException;
36 import javax.crypto.NoSuchPaddingException;
37 import javax.crypto.SecretKey;
38 import javax.crypto.SecretKeyFactory;
39 import javax.crypto.ShortBufferException;
40 import javax.crypto.spec.PBEKeySpec;
41 import javax.crypto.spec.PBEParameterSpec;
42 
43 /*
44  * @test
45  * @bug 8048601
46  * @summary Tests for PBE ciphers
47  */
48 public class TestCipherPBE {
49 
50     private static final String[] ALGORITHMS = {"PBEWithMD5AndDES",
51         "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndTripleDES",
52         "PBEWithMD5AndTripleDES/CBC/PKCS5Padding"};
53 
54     private static final String KEY_ALGO = "pbeWithMD5ANDdes";
55     private final byte[] SALT;
56     private final byte[] PLAIN_TEXT;
57 
TestCipherPBE()58     public TestCipherPBE() {
59         SALT = generateBytes(8);
60         PLAIN_TEXT = generateBytes(200);
61     }
62 
main(String[] args)63     public static void main(String[] args) throws Exception {
64 
65         new TestCipherPBE().runAll();
66     }
67 
runAll()68     private void runAll() throws Exception {
69         for (String algorithm : ALGORITHMS) {
70             runTest(algorithm);
71         }
72     }
73 
runTest(String algorithm)74     private void runTest(String algorithm)
75             throws InvalidKeySpecException, NoSuchAlgorithmException,
76             InvalidAlgorithmParameterException, ShortBufferException,
77             NoSuchPaddingException, IllegalBlockSizeException,
78             BadPaddingException, InvalidKeyException {
79 
80         out.println("=> Testing: " + algorithm);
81 
82         boolean isUnlimited =
83             (Cipher.getMaxAllowedKeyLength(algorithm) == Integer.MAX_VALUE);
84 
85         try {
86             // Initialization
87             AlgorithmParameterSpec algoParamSpec
88                     = new PBEParameterSpec(SALT, 6);
89 
90             SecretKey secretKey
91                     = SecretKeyFactory.getInstance(KEY_ALGO).generateSecret(
92                     new PBEKeySpec(("Secret Key Value").toCharArray()));
93 
94             Cipher ci = Cipher.getInstance(algorithm);
95             ci.init(Cipher.ENCRYPT_MODE, secretKey, algoParamSpec);
96 
97             // Encryption
98             byte[] cipherText = ci.doFinal(PLAIN_TEXT);
99 
100             // Decryption
101             ci.init(Cipher.DECRYPT_MODE, secretKey, algoParamSpec);
102             byte[] recoveredText = ci.doFinal(cipherText);
103 
104             if (algorithm.contains("TripleDES") && !isUnlimited) {
105                 throw new RuntimeException(
106                         "Expected InvalidKeyException not thrown");
107             }
108 
109             // Comparison
110             if (!Arrays.equals(PLAIN_TEXT, recoveredText)) {
111                 throw new RuntimeException(
112                         "Test failed: plainText is not equal to recoveredText");
113             }
114             out.println("Test Passed.");
115         } catch (InvalidKeyException ex) {
116             if (algorithm.contains("TripleDES") && !isUnlimited) {
117                 out.println("Expected InvalidKeyException thrown");
118             } else {
119                 throw new RuntimeException(ex);
120             }
121         }
122     }
123 
generateBytes(int length)124     public static byte[] generateBytes(int length) {
125         byte[] bytes = new byte[length];
126         for (int i = 0; i < length; i++) {
127             bytes[i] = (byte) (i & 0xff);
128         }
129         return bytes;
130     }
131 }
132