71 (javax.crypto.interfaces.PBEKey) key; |
71 (javax.crypto.interfaces.PBEKey) key; |
72 passwdChars = pbeKey.getPassword(); |
72 passwdChars = pbeKey.getPassword(); |
73 salt = pbeKey.getSalt(); // maybe null if unspecified |
73 salt = pbeKey.getSalt(); // maybe null if unspecified |
74 iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified |
74 iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified |
75 } else if (key instanceof SecretKey) { |
75 } else if (key instanceof SecretKey) { |
76 byte[] passwdBytes = key.getEncoded(); |
76 byte[] passwdBytes; |
77 if ((passwdBytes == null) || |
77 if (!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3)) || |
78 !(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3))) { |
78 (passwdBytes = key.getEncoded()) == null) { |
79 throw new InvalidKeyException("Missing password"); |
79 throw new InvalidKeyException("Missing password"); |
80 } |
80 } |
81 passwdChars = new char[passwdBytes.length]; |
81 passwdChars = new char[passwdBytes.length]; |
82 for (int i=0; i<passwdChars.length; i++) { |
82 for (int i=0; i<passwdChars.length; i++) { |
83 passwdChars[i] = (char) (passwdBytes[i] & 0x7f); |
83 passwdChars[i] = (char) (passwdBytes[i] & 0x7f); |
84 } |
84 } |
|
85 Arrays.fill(passwdBytes, (byte)0x00); |
85 } else { |
86 } else { |
86 throw new InvalidKeyException("SecretKey of PBE type required"); |
87 throw new InvalidKeyException("SecretKey of PBE type required"); |
87 } |
88 } |
88 if (params == null) { |
89 |
89 // should not auto-generate default values since current |
90 byte[] derivedKey; |
90 // javax.crypto.Mac api does not have any method for caller to |
91 try { |
91 // retrieve the generated defaults. |
92 if (params == null) { |
92 if ((salt == null) || (iCount == 0)) { |
93 // should not auto-generate default values since current |
|
94 // javax.crypto.Mac api does not have any method for caller to |
|
95 // retrieve the generated defaults. |
|
96 if ((salt == null) || (iCount == 0)) { |
|
97 throw new InvalidAlgorithmParameterException |
|
98 ("PBEParameterSpec required for salt and iteration count"); |
|
99 } |
|
100 } else if (!(params instanceof PBEParameterSpec)) { |
93 throw new InvalidAlgorithmParameterException |
101 throw new InvalidAlgorithmParameterException |
94 ("PBEParameterSpec required for salt and iteration count"); |
102 ("PBEParameterSpec type required"); |
|
103 } else { |
|
104 PBEParameterSpec pbeParams = (PBEParameterSpec) params; |
|
105 // make sure the parameter values are consistent |
|
106 if (salt != null) { |
|
107 if (!Arrays.equals(salt, pbeParams.getSalt())) { |
|
108 throw new InvalidAlgorithmParameterException |
|
109 ("Inconsistent value of salt between key and params"); |
|
110 } |
|
111 } else { |
|
112 salt = pbeParams.getSalt(); |
|
113 } |
|
114 if (iCount != 0) { |
|
115 if (iCount != pbeParams.getIterationCount()) { |
|
116 throw new InvalidAlgorithmParameterException |
|
117 ("Different iteration count between key and params"); |
|
118 } |
|
119 } else { |
|
120 iCount = pbeParams.getIterationCount(); |
|
121 } |
95 } |
122 } |
96 } else if (!(params instanceof PBEParameterSpec)) { |
123 // For security purpose, we need to enforce a minimum length |
97 throw new InvalidAlgorithmParameterException |
124 // for salt; just require the minimum salt length to be 8-byte |
98 ("PBEParameterSpec type required"); |
125 // which is what PKCS#5 recommends and openssl does. |
99 } else { |
126 if (salt.length < 8) { |
100 PBEParameterSpec pbeParams = (PBEParameterSpec) params; |
127 throw new InvalidAlgorithmParameterException |
101 // make sure the parameter values are consistent |
128 ("Salt must be at least 8 bytes long"); |
102 if (salt != null) { |
|
103 if (!Arrays.equals(salt, pbeParams.getSalt())) { |
|
104 throw new InvalidAlgorithmParameterException |
|
105 ("Inconsistent value of salt between key and params"); |
|
106 } |
|
107 } else { |
|
108 salt = pbeParams.getSalt(); |
|
109 } |
129 } |
110 if (iCount != 0) { |
130 if (iCount <= 0) { |
111 if (iCount != pbeParams.getIterationCount()) { |
131 throw new InvalidAlgorithmParameterException |
112 throw new InvalidAlgorithmParameterException |
132 ("IterationCount must be a positive number"); |
113 ("Different iteration count between key and params"); |
|
114 } |
|
115 } else { |
|
116 iCount = pbeParams.getIterationCount(); |
|
117 } |
133 } |
|
134 derivedKey = PKCS12PBECipherCore.derive(passwdChars, salt, |
|
135 iCount, engineGetMacLength(), PKCS12PBECipherCore.MAC_KEY); |
|
136 } finally { |
|
137 Arrays.fill(passwdChars, '\0'); |
118 } |
138 } |
119 // For security purpose, we need to enforce a minimum length |
|
120 // for salt; just require the minimum salt length to be 8-byte |
|
121 // which is what PKCS#5 recommends and openssl does. |
|
122 if (salt.length < 8) { |
|
123 throw new InvalidAlgorithmParameterException |
|
124 ("Salt must be at least 8 bytes long"); |
|
125 } |
|
126 if (iCount <= 0) { |
|
127 throw new InvalidAlgorithmParameterException |
|
128 ("IterationCount must be a positive number"); |
|
129 } |
|
130 byte[] derivedKey = PKCS12PBECipherCore.derive(passwdChars, salt, |
|
131 iCount, engineGetMacLength(), PKCS12PBECipherCore.MAC_KEY); |
|
132 SecretKey cipherKey = new SecretKeySpec(derivedKey, "HmacSHA1"); |
139 SecretKey cipherKey = new SecretKeySpec(derivedKey, "HmacSHA1"); |
133 super.engineInit(cipherKey, null); |
140 super.engineInit(cipherKey, null); |
134 } |
141 } |
135 } |
142 } |