Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
0bc93426
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
0bc93426
编写于
8月 24, 2018
作者:
C
coffeys
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8209129: Further improvements to cipher buffer management
Reviewed-by: weijun, igerasim
上级
175b0d98
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
352 addition
and
280 deletion
+352
-280
src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java
...re/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java
+48
-41
src/share/classes/com/sun/crypto/provider/KeyProtector.java
src/share/classes/com/sun/crypto/provider/KeyProtector.java
+2
-2
src/share/classes/com/sun/crypto/provider/PBEKey.java
src/share/classes/com/sun/crypto/provider/PBEKey.java
+2
-2
src/share/classes/com/sun/crypto/provider/PBES1Core.java
src/share/classes/com/sun/crypto/provider/PBES1Core.java
+42
-33
src/share/classes/com/sun/crypto/provider/PBES2Core.java
src/share/classes/com/sun/crypto/provider/PBES2Core.java
+88
-83
src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
+8
-4
src/share/classes/com/sun/crypto/provider/PBMAC1Core.java
src/share/classes/com/sun/crypto/provider/PBMAC1Core.java
+49
-45
src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java
.../classes/com/sun/crypto/provider/PKCS12PBECipherCore.java
+68
-62
src/share/classes/sun/security/provider/DigestBase.java
src/share/classes/sun/security/provider/DigestBase.java
+2
-0
src/share/classes/sun/security/provider/MD4.java
src/share/classes/sun/security/provider/MD4.java
+8
-1
src/share/classes/sun/security/provider/MD5.java
src/share/classes/sun/security/provider/MD5.java
+9
-1
src/share/classes/sun/security/provider/SHA.java
src/share/classes/sun/security/provider/SHA.java
+10
-1
src/share/classes/sun/security/provider/SHA2.java
src/share/classes/sun/security/provider/SHA2.java
+8
-1
src/share/classes/sun/security/provider/SHA5.java
src/share/classes/sun/security/provider/SHA5.java
+7
-3
test/com/sun/crypto/provider/Cipher/PBE/PKCS12Cipher.java
test/com/sun/crypto/provider/Cipher/PBE/PKCS12Cipher.java
+1
-1
未找到文件。
src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java
浏览文件 @
0bc93426
...
...
@@ -73,62 +73,69 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
salt
=
pbeKey
.
getSalt
();
// maybe null if unspecified
iCount
=
pbeKey
.
getIterationCount
();
// maybe 0 if unspecified
}
else
if
(
key
instanceof
SecretKey
)
{
byte
[]
passwdBytes
=
key
.
getEncoded
()
;
if
(
(
passwdBytes
==
null
)
||
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
))
)
{
byte
[]
passwdBytes
;
if
(
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
)
)
||
(
passwdBytes
=
key
.
getEncoded
())
==
null
)
{
throw
new
InvalidKeyException
(
"Missing password"
);
}
passwdChars
=
new
char
[
passwdBytes
.
length
];
for
(
int
i
=
0
;
i
<
passwdChars
.
length
;
i
++)
{
passwdChars
[
i
]
=
(
char
)
(
passwdBytes
[
i
]
&
0x7f
);
}
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
}
else
{
throw
new
InvalidKeyException
(
"SecretKey of PBE type required"
);
}
if
(
params
==
null
)
{
// should not auto-generate default values since current
// javax.crypto.Mac api does not have any method for caller to
// retrieve the generated defaults.
if
((
salt
==
null
)
||
(
iCount
==
0
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec required for salt and iteration count"
);
}
}
else
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec type required"
);
}
else
{
PBEParameterSpec
pbeParams
=
(
PBEParameterSpec
)
params
;
// make sure the parameter values are consistent
if
(
salt
!=
null
)
{
if
(!
Arrays
.
equals
(
salt
,
pbeParams
.
getSalt
()))
{
byte
[]
derivedKey
;
try
{
if
(
params
==
null
)
{
// should not auto-generate default values since current
// javax.crypto.Mac api does not have any method for caller to
// retrieve the generated defaults.
if
((
salt
==
null
)
||
(
iCount
==
0
))
{
throw
new
InvalidAlgorithmParameterException
(
"Inconsistent value of salt between key and params
"
);
(
"PBEParameterSpec required for salt and iteration count
"
);
}
}
else
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec type required"
);
}
else
{
salt
=
pbeParams
.
getSalt
();
}
if
(
iCount
!=
0
)
{
if
(
iCount
!=
pbeParams
.
getIterationCount
())
{
throw
new
InvalidAlgorithmParameterException
(
"Different iteration count between key and params"
);
PBEParameterSpec
pbeParams
=
(
PBEParameterSpec
)
params
;
// make sure the parameter values are consistent
if
(
salt
!=
null
)
{
if
(!
Arrays
.
equals
(
salt
,
pbeParams
.
getSalt
()))
{
throw
new
InvalidAlgorithmParameterException
(
"Inconsistent value of salt between key and params"
);
}
}
else
{
salt
=
pbeParams
.
getSalt
();
}
if
(
iCount
!=
0
)
{
if
(
iCount
!=
pbeParams
.
getIterationCount
())
{
throw
new
InvalidAlgorithmParameterException
(
"Different iteration count between key and params"
);
}
}
else
{
iCount
=
pbeParams
.
getIterationCount
();
}
}
else
{
iCount
=
pbeParams
.
getIterationCount
();
}
// For security purpose, we need to enforce a minimum length
// for salt; just require the minimum salt length to be 8-byte
// which is what PKCS#5 recommends and openssl does.
if
(
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
}
derivedKey
=
PKCS12PBECipherCore
.
derive
(
passwdChars
,
salt
,
iCount
,
engineGetMacLength
(),
PKCS12PBECipherCore
.
MAC_KEY
);
}
finally
{
Arrays
.
fill
(
passwdChars
,
'\0'
);
}
// For security purpose, we need to enforce a minimum length
// for salt; just require the minimum salt length to be 8-byte
// which is what PKCS#5 recommends and openssl does.
if
(
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
}
byte
[]
derivedKey
=
PKCS12PBECipherCore
.
derive
(
passwdChars
,
salt
,
iCount
,
engineGetMacLength
(),
PKCS12PBECipherCore
.
MAC_KEY
);
SecretKey
cipherKey
=
new
SecretKeySpec
(
derivedKey
,
"HmacSHA1"
);
super
.
engineInit
(
cipherKey
,
null
);
}
...
...
src/share/classes/com/sun/crypto/provider/KeyProtector.java
浏览文件 @
0bc93426
...
...
@@ -119,7 +119,7 @@ final class KeyProtector {
}
byte
[]
plain
=
key
.
getEncoded
();
byte
[]
encrKey
=
cipher
.
engineDoFinal
(
plain
,
0
,
plain
.
length
);
Arrays
.
fill
(
plain
,
(
byte
)
0x00
);
Arrays
.
fill
(
plain
,
(
byte
)
0x00
);
// wrap encrypted private key in EncryptedPrivateKeyInfo
// (as defined in PKCS#8)
...
...
@@ -194,7 +194,7 @@ final class KeyProtector {
}
catch
(
GeneralSecurityException
gse
)
{
throw
new
UnrecoverableKeyException
(
gse
.
getMessage
());
}
finally
{
if
(
plain
!=
null
)
Arrays
.
fill
(
plain
,
(
byte
)
0x00
);
if
(
plain
!=
null
)
Arrays
.
fill
(
plain
,
(
byte
)
0x00
);
if
(
sKey
!=
null
)
{
try
{
sKey
.
destroy
();
...
...
src/share/classes/com/sun/crypto/provider/PBEKey.java
浏览文件 @
0bc93426
...
...
@@ -69,7 +69,7 @@ final class PBEKey implements SecretKey {
this
.
key
=
new
byte
[
passwd
.
length
];
for
(
int
i
=
0
;
i
<
passwd
.
length
;
i
++)
this
.
key
[
i
]
=
(
byte
)
(
passwd
[
i
]
&
0x7f
);
Arrays
.
fill
(
passwd
,
'
'
);
Arrays
.
fill
(
passwd
,
'
\0
'
);
type
=
keytype
;
}
...
...
@@ -122,7 +122,7 @@ final class PBEKey implements SecretKey {
@Override
public
void
destroy
()
{
if
(
key
!=
null
)
{
Arrays
.
fill
(
key
,
(
byte
)
0x00
);
Arrays
.
fill
(
key
,
(
byte
)
0x00
);
key
=
null
;
}
}
...
...
src/share/classes/com/sun/crypto/provider/PBES1Core.java
浏览文件 @
0bc93426
...
...
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import
java.security.*
;
import
java.security.spec.*
;
import
java.util.Arrays
;
import
javax.crypto.*
;
import
javax.crypto.spec.*
;
...
...
@@ -213,35 +214,43 @@ final class PBES1Core {
throw
new
InvalidAlgorithmParameterException
(
"Parameters "
+
"missing"
);
}
if
((
key
==
null
)
||
(
key
.
getEncoded
()
==
null
)
||
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
)))
{
throw
new
InvalidKeyException
(
"Missing password"
);
if
(
key
==
null
)
{
throw
new
InvalidKeyException
(
"Null key"
);
}
if
(
params
==
null
)
{
// create random salt and use default iteration count
salt
=
new
byte
[
8
];
random
.
nextBytes
(
salt
);
}
else
{
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"Wrong parameter type: PBE expected"
);
}
salt
=
((
PBEParameterSpec
)
params
).
getSalt
();
// salt must be 8 bytes long (by definition)
if
(
salt
.
length
!=
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be 8 bytes long"
);
byte
[]
derivedKey
;
byte
[]
passwdBytes
=
key
.
getEncoded
();
try
{
if
((
passwdBytes
==
null
)
||
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
)))
{
throw
new
InvalidKeyException
(
"Missing password"
);
}
iCount
=
((
PBEParameterSpec
)
params
).
getIterationCount
();
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
if
(
params
==
null
)
{
// create random salt and use default iteration count
salt
=
new
byte
[
8
];
random
.
nextBytes
(
salt
);
}
else
{
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"Wrong parameter type: PBE expected"
);
}
salt
=
((
PBEParameterSpec
)
params
).
getSalt
();
// salt must be 8 bytes long (by definition)
if
(
salt
.
length
!=
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be 8 bytes long"
);
}
iCount
=
((
PBEParameterSpec
)
params
).
getIterationCount
();
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
}
}
derivedKey
=
deriveCipherKey
(
passwdBytes
);
}
finally
{
if
(
passwdBytes
!=
null
)
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
}
byte
[]
derivedKey
=
deriveCipherKey
(
key
);
// use all but the last 8 bytes as the key value
SecretKeySpec
cipherKey
=
new
SecretKeySpec
(
derivedKey
,
0
,
derivedKey
.
length
-
8
,
algo
);
...
...
@@ -253,16 +262,14 @@ final class PBES1Core {
cipher
.
init
(
opmode
,
cipherKey
,
ivSpec
,
random
);
}
private
byte
[]
deriveCipherKey
(
Key
key
)
{
private
byte
[]
deriveCipherKey
(
byte
[]
passwdBytes
)
{
byte
[]
result
=
null
;
byte
[]
passwdBytes
=
key
.
getEncoded
();
if
(
algo
.
equals
(
"DES"
))
{
// P || S (password concatenated with salt)
byte
[]
concat
=
new
byte
[
Math
.
addExact
(
passwdBytes
.
length
,
salt
.
length
)];
System
.
arraycopy
(
passwdBytes
,
0
,
concat
,
0
,
passwdBytes
.
length
);
java
.
util
.
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
System
.
arraycopy
(
salt
,
0
,
concat
,
passwdBytes
.
length
,
salt
.
length
);
// digest P || S with c iterations
...
...
@@ -271,7 +278,7 @@ final class PBES1Core {
md
.
update
(
toBeHashed
);
toBeHashed
=
md
.
digest
();
// this resets the digest
}
java
.
util
.
Arrays
.
fill
(
concat
,
(
byte
)
0x00
);
Arrays
.
fill
(
concat
,
(
byte
)
0x00
);
result
=
toBeHashed
;
}
else
if
(
algo
.
equals
(
"DESede"
))
{
// if the 2 salt halves are the same, invert one of them
...
...
@@ -294,8 +301,6 @@ final class PBES1Core {
// Concatenate the output from each digest round with the
// password, and use the result as the input to the next digest
// operation.
byte
[]
kBytes
=
null
;
IvParameterSpec
iv
=
null
;
byte
[]
toBeHashed
=
null
;
result
=
new
byte
[
DESedeKeySpec
.
DES_EDE_KEY_LEN
+
DESConstants
.
DES_BLOCK_SIZE
];
...
...
@@ -306,12 +311,14 @@ final class PBES1Core {
for
(
int
j
=
0
;
j
<
iCount
;
j
++)
{
md
.
update
(
toBeHashed
);
md
.
update
(
passwdBytes
);
toBeHashed
=
md
.
digest
();
// this resets the digest
toBeHashed
=
md
.
digest
();
}
System
.
arraycopy
(
toBeHashed
,
0
,
result
,
i
*
16
,
toBeHashed
.
length
);
}
}
// clear data used in message
md
.
reset
();
return
result
;
}
...
...
@@ -478,9 +485,9 @@ final class PBES1Core {
byte
[]
wrap
(
Key
key
)
throws
IllegalBlockSizeException
,
InvalidKeyException
{
byte
[]
result
=
null
;
byte
[]
encodedKey
=
null
;
try
{
byte
[]
encodedKey
=
key
.
getEncoded
();
encodedKey
=
key
.
getEncoded
();
if
((
encodedKey
==
null
)
||
(
encodedKey
.
length
==
0
))
{
throw
new
InvalidKeyException
(
"Cannot get an encoding of "
+
"the key to be wrapped"
);
...
...
@@ -489,6 +496,8 @@ final class PBES1Core {
result
=
doFinal
(
encodedKey
,
0
,
encodedKey
.
length
);
}
catch
(
BadPaddingException
e
)
{
// Should never happen
}
finally
{
if
(
encodedKey
!=
null
)
Arrays
.
fill
(
encodedKey
,
(
byte
)
0x00
);
}
return
result
;
...
...
src/share/classes/com/sun/crypto/provider/PBES2Core.java
浏览文件 @
0bc93426
...
...
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import
java.security.*
;
import
java.security.spec.*
;
import
java.util.Arrays
;
import
javax.crypto.*
;
import
javax.crypto.spec.*
;
...
...
@@ -173,101 +174,105 @@ abstract class PBES2Core extends CipherSpi {
SecureRandom
random
)
throws
InvalidKeyException
,
InvalidAlgorithmParameterException
{
if
((
key
==
null
)
||
(
key
.
getEncoded
()
==
null
)
||
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
)))
{
throw
new
InvalidKeyException
(
"Missing password"
);
if
(
key
==
null
)
{
throw
new
InvalidKeyException
(
"Null key"
);
}
// TBD: consolidate the salt, ic and IV parameter checks below
// Extract salt and iteration count from the key, if present
if
(
key
instanceof
javax
.
crypto
.
interfaces
.
PBEKey
)
{
salt
=
((
javax
.
crypto
.
interfaces
.
PBEKey
)
key
).
getSalt
();
if
(
salt
!=
null
&&
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
iCount
=
((
javax
.
crypto
.
interfaces
.
PBEKey
)
key
).
getIterationCount
();
if
(
iCount
==
0
)
{
iCount
=
DEFAULT_COUNT
;
}
else
if
(
iCount
<
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"Iteration count must be a positive number"
);
byte
[]
passwdBytes
=
key
.
getEncoded
();
char
[]
passwdChars
=
null
;
PBEKeySpec
pbeSpec
;
try
{
if
((
passwdBytes
==
null
)
||
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
)))
{
throw
new
InvalidKeyException
(
"Missing password"
);
}
}
// Extract salt, iteration count and IV from the params, if present
if
(
params
==
null
)
{
if
(
salt
==
null
)
{
// generate random salt and use default iteration count
salt
=
new
byte
[
DEFAULT_SALT_LENGTH
];
random
.
nextBytes
(
salt
);
iCount
=
DEFAULT_COUNT
;
}
if
((
opmode
==
Cipher
.
ENCRYPT_MODE
)
||
(
opmode
==
Cipher
.
WRAP_MODE
))
{
// generate random IV
byte
[]
ivBytes
=
new
byte
[
blkSize
];
random
.
nextBytes
(
ivBytes
);
ivSpec
=
new
IvParameterSpec
(
ivBytes
);
}
}
else
{
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"Wrong parameter type: PBE expected"
);
}
// salt and iteration count from the params take precedence
byte
[]
specSalt
=
((
PBEParameterSpec
)
params
).
getSalt
();
if
(
specSalt
!=
null
&&
specSalt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
salt
=
specSalt
;
int
specICount
=
((
PBEParameterSpec
)
params
).
getIterationCount
();
if
(
specICount
==
0
)
{
specICount
=
DEFAULT_COUNT
;
}
else
if
(
specICount
<
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"Iteration count must be a positive number"
);
}
iCount
=
specICount
;
// TBD: consolidate the salt, ic and IV parameter checks below
AlgorithmParameterSpec
specParams
=
((
PBEParameterSpec
)
params
).
getParameterSpec
();
if
(
specParams
!=
null
)
{
if
(
specParams
instanceof
IvParameterSpec
)
{
ivSpec
=
(
IvParameterSpec
)
specParams
;
}
else
{
// Extract salt and iteration count from the key, if present
if
(
key
instanceof
javax
.
crypto
.
interfaces
.
PBEKey
)
{
salt
=
((
javax
.
crypto
.
interfaces
.
PBEKey
)
key
).
getSalt
();
if
(
salt
!=
null
&&
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
iCount
=
((
javax
.
crypto
.
interfaces
.
PBEKey
)
key
).
getIterationCount
();
if
(
iCount
==
0
)
{
iCount
=
DEFAULT_COUNT
;
}
else
if
(
iCount
<
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"Wrong parameter type: IV expected
"
);
"Iteration count must be a positive number
"
);
}
}
else
if
((
opmode
==
Cipher
.
ENCRYPT_MODE
)
||
}
// Extract salt, iteration count and IV from the params, if present
if
(
params
==
null
)
{
if
(
salt
==
null
)
{
// generate random salt and use default iteration count
salt
=
new
byte
[
DEFAULT_SALT_LENGTH
];
random
.
nextBytes
(
salt
);
iCount
=
DEFAULT_COUNT
;
}
if
((
opmode
==
Cipher
.
ENCRYPT_MODE
)
||
(
opmode
==
Cipher
.
WRAP_MODE
))
{
// generate random IV
byte
[]
ivBytes
=
new
byte
[
blkSize
];
random
.
nextBytes
(
ivBytes
);
ivSpec
=
new
IvParameterSpec
(
ivBytes
);
// generate random IV
byte
[]
ivBytes
=
new
byte
[
blkSize
];
random
.
nextBytes
(
ivBytes
);
ivSpec
=
new
IvParameterSpec
(
ivBytes
);
}
}
else
{
throw
new
InvalidAlgorithmParameterException
(
"Missing parameter type: IV expected"
);
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"Wrong parameter type: PBE expected"
);
}
// salt and iteration count from the params take precedence
byte
[]
specSalt
=
((
PBEParameterSpec
)
params
).
getSalt
();
if
(
specSalt
!=
null
&&
specSalt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
salt
=
specSalt
;
int
specICount
=
((
PBEParameterSpec
)
params
).
getIterationCount
();
if
(
specICount
==
0
)
{
specICount
=
DEFAULT_COUNT
;
}
else
if
(
specICount
<
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"Iteration count must be a positive number"
);
}
iCount
=
specICount
;
AlgorithmParameterSpec
specParams
=
((
PBEParameterSpec
)
params
).
getParameterSpec
();
if
(
specParams
!=
null
)
{
if
(
specParams
instanceof
IvParameterSpec
)
{
ivSpec
=
(
IvParameterSpec
)
specParams
;
}
else
{
throw
new
InvalidAlgorithmParameterException
(
"Wrong parameter type: IV expected"
);
}
}
else
if
((
opmode
==
Cipher
.
ENCRYPT_MODE
)
||
(
opmode
==
Cipher
.
WRAP_MODE
))
{
// generate random IV
byte
[]
ivBytes
=
new
byte
[
blkSize
];
random
.
nextBytes
(
ivBytes
);
ivSpec
=
new
IvParameterSpec
(
ivBytes
);
}
else
{
throw
new
InvalidAlgorithmParameterException
(
"Missing parameter type: IV expected"
);
}
}
}
SecretKeySpec
cipherKey
=
null
;
byte
[]
derivedKey
=
null
;
byte
[]
passwdBytes
=
key
.
getEncoded
();
char
[]
passwdChars
=
new
char
[
passwdBytes
.
length
];
for
(
int
i
=
0
;
i
<
passwdChars
.
length
;
i
++)
passwdChars
[
i
]
=
(
char
)
(
passwdBytes
[
i
]
&
0x7f
);
passwdChars
=
new
char
[
passwdBytes
.
length
];
for
(
int
i
=
0
;
i
<
passwdChars
.
length
;
i
++)
passwdChars
[
i
]
=
(
char
)
(
passwdBytes
[
i
]
&
0x7f
);
PBEKeySpec
pbeSpec
=
new
PBEKeySpec
(
passwdChars
,
salt
,
iCount
,
keyLength
);
pbeSpec
=
new
PBEKeySpec
(
passwdChars
,
salt
,
iCount
,
keyLength
);
// password char[] was cloned in PBEKeySpec constructor,
// so we can zero it out here
java
.
util
.
Arrays
.
fill
(
passwdChars
,
' '
);
java
.
util
.
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
}
finally
{
if
(
passwdChars
!=
null
)
Arrays
.
fill
(
passwdChars
,
'\0'
);
if
(
passwdBytes
!=
null
)
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
}
SecretKey
s
=
null
;
...
...
@@ -280,8 +285,8 @@ abstract class PBES2Core extends CipherSpi {
ike
.
initCause
(
ikse
);
throw
ike
;
}
derivedKey
=
s
.
getEncoded
();
cipherKey
=
new
SecretKeySpec
(
derivedKey
,
cipherAlgo
);
byte
[]
derivedKey
=
s
.
getEncoded
();
SecretKeySpec
cipherKey
=
new
SecretKeySpec
(
derivedKey
,
cipherAlgo
);
// initialize the underlying cipher
cipher
.
init
(
opmode
,
cipherKey
,
ivSpec
,
random
);
...
...
src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
浏览文件 @
0bc93426
...
...
@@ -89,6 +89,8 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
}
// Convert the password from char[] to byte[]
byte
[]
passwdBytes
=
getPasswordBytes
(
this
.
passwd
);
// remove local copy
if
(
passwd
!=
null
)
Arrays
.
fill
(
passwd
,
'\0'
);
this
.
salt
=
keySpec
.
getSalt
();
if
(
salt
==
null
)
{
...
...
@@ -108,13 +110,15 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
}
try
{
this
.
prf
=
Mac
.
getInstance
(
prfAlgo
,
SunJCE
.
getInstance
());
this
.
key
=
deriveKey
(
prf
,
passwdBytes
,
salt
,
iterCount
,
keyLength
);
}
catch
(
NoSuchAlgorithmException
nsae
)
{
// not gonna happen; re-throw just in case
InvalidKeySpecException
ike
=
new
InvalidKeySpecException
();
ike
.
initCause
(
nsae
);
throw
ike
;
}
finally
{
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
}
this
.
key
=
deriveKey
(
prf
,
passwdBytes
,
salt
,
iterCount
,
keyLength
);
}
private
static
byte
[]
deriveKey
(
final
Mac
prf
,
final
byte
[]
password
,
...
...
@@ -240,8 +244,8 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
if
(!(
that
.
getFormat
().
equalsIgnoreCase
(
"RAW"
)))
return
false
;
byte
[]
thatEncoded
=
that
.
getEncoded
();
boolean
ret
=
MessageDigest
.
isEqual
(
key
,
that
.
getEncoded
()
);
java
.
util
.
Arrays
.
fill
(
thatEncoded
,
(
byte
)
0x00
);
boolean
ret
=
MessageDigest
.
isEqual
(
key
,
that
Encoded
);
Arrays
.
fill
(
thatEncoded
,
(
byte
)
0x00
);
return
ret
;
}
...
...
@@ -266,7 +270,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
try
{
synchronized
(
this
)
{
if
(
this
.
passwd
!=
null
)
{
java
.
util
.
Arrays
.
fill
(
this
.
passwd
,
'0'
);
java
.
util
.
Arrays
.
fill
(
this
.
passwd
,
'
\
0'
);
this
.
passwd
=
null
;
}
if
(
this
.
key
!=
null
)
{
...
...
src/share/classes/com/sun/crypto/provider/PBMAC1Core.java
浏览文件 @
0bc93426
...
...
@@ -108,72 +108,76 @@ abstract class PBMAC1Core extends HmacCore {
salt
=
pbeKey
.
getSalt
();
// maybe null if unspecified
iCount
=
pbeKey
.
getIterationCount
();
// maybe 0 if unspecified
}
else
if
(
key
instanceof
SecretKey
)
{
byte
[]
passwdBytes
=
key
.
getEncoded
()
;
if
(
(
passwdBytes
==
null
)
||
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
))
)
{
byte
[]
passwdBytes
;
if
(
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
)
)
||
(
passwdBytes
=
key
.
getEncoded
())
==
null
)
{
throw
new
InvalidKeyException
(
"Missing password"
);
}
passwdChars
=
new
char
[
passwdBytes
.
length
];
for
(
int
i
=
0
;
i
<
passwdChars
.
length
;
i
++)
{
passwdChars
[
i
]
=
(
char
)
(
passwdBytes
[
i
]
&
0x7f
);
}
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
}
else
{
throw
new
InvalidKeyException
(
"SecretKey of PBE type required"
);
}
if
(
params
==
null
)
{
// should not auto-generate default values since current
// javax.crypto.Mac api does not have any method for caller to
// retrieve the generated defaults.
if
((
salt
==
null
)
||
(
iCount
==
0
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec required for salt and iteration count"
);
}
}
else
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec type required"
);
}
else
{
PBEParameterSpec
pbeParams
=
(
PBEParameterSpec
)
params
;
// make sure the parameter values are consistent
if
(
salt
!=
null
)
{
if
(!
Arrays
.
equals
(
salt
,
pbeParams
.
getSalt
()))
{
PBEKeySpec
pbeSpec
;
try
{
if
(
params
==
null
)
{
// should not auto-generate default values since current
// javax.crypto.Mac api does not have any method for caller to
// retrieve the generated defaults.
if
((
salt
==
null
)
||
(
iCount
==
0
))
{
throw
new
InvalidAlgorithmParameterException
(
"Inconsistent value of salt between key and params
"
);
(
"PBEParameterSpec required for salt and iteration count
"
);
}
}
else
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec type required"
);
}
else
{
salt
=
pbeParams
.
getSalt
();
}
if
(
iCount
!=
0
)
{
if
(
iCount
!=
pbeParams
.
getIterationCount
())
{
throw
new
InvalidAlgorithmParameterException
(
"Different iteration count between key and params"
);
PBEParameterSpec
pbeParams
=
(
PBEParameterSpec
)
params
;
// make sure the parameter values are consistent
if
(
salt
!=
null
)
{
if
(!
Arrays
.
equals
(
salt
,
pbeParams
.
getSalt
()))
{
throw
new
InvalidAlgorithmParameterException
(
"Inconsistent value of salt between key and params"
);
}
}
else
{
salt
=
pbeParams
.
getSalt
();
}
if
(
iCount
!=
0
)
{
if
(
iCount
!=
pbeParams
.
getIterationCount
())
{
throw
new
InvalidAlgorithmParameterException
(
"Different iteration count between key and params"
);
}
}
else
{
iCount
=
pbeParams
.
getIterationCount
();
}
}
else
{
iCount
=
pbeParams
.
getIterationCount
();
}
}
// For security purpose, we need to enforce a minimum length
// for salt; just require the minimum salt length to be 8-byte
// which is what PKCS#5 recommends and openssl does.
if
(
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
}
// For security purpose, we need to enforce a minimum length
// for salt; just require the minimum salt length to be 8-byte
// which is what PKCS#5 recommends and openssl does.
if
(
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
}
PBEKeySpec
pbeSpec
=
new
PBEKeySpec
(
passwdChars
,
salt
,
iCount
,
blockLength
);
pbeSpec
=
new
PBEKeySpec
(
passwdChars
,
salt
,
iCount
,
blockLength
);
// password char[] was cloned in PBEKeySpec constructor,
// so we can zero it out here
java
.
util
.
Arrays
.
fill
(
passwdChars
,
' '
);
}
finally
{
Arrays
.
fill
(
passwdChars
,
'\0'
);
}
SecretKey
s
=
null
;
SecretKey
s
;
PBKDF2Core
kdf
=
getKDFImpl
(
kdfAlgo
);
try
{
s
=
kdf
.
engineGenerateSecret
(
pbeSpec
);
}
catch
(
InvalidKeySpecException
ikse
)
{
InvalidKeyException
ike
=
new
InvalidKeyException
(
"Cannot construct PBE key"
);
...
...
src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java
浏览文件 @
0bc93426
...
...
@@ -103,6 +103,7 @@ final class PKCS12PBECipherCore {
Arrays
.
fill
(
D
,
(
byte
)
type
);
concat
(
salt
,
I
,
0
,
s
);
concat
(
passwd
,
I
,
s
,
p
);
Arrays
.
fill
(
passwd
,
(
byte
)
0x00
);
byte
[]
Ai
;
byte
[]
B
=
new
byte
[
v
];
...
...
@@ -265,87 +266,92 @@ final class PKCS12PBECipherCore {
salt
=
pbeKey
.
getSalt
();
// maybe null if unspecified
iCount
=
pbeKey
.
getIterationCount
();
// maybe 0 if unspecified
}
else
if
(
key
instanceof
SecretKey
)
{
byte
[]
passwdBytes
=
key
.
getEncoded
()
;
if
(
(
passwdBytes
==
null
)
||
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
))
)
{
byte
[]
passwdBytes
;
if
(
!(
key
.
getAlgorithm
().
regionMatches
(
true
,
0
,
"PBE"
,
0
,
3
)
)
||
(
passwdBytes
=
key
.
getEncoded
())
==
null
)
{
throw
new
InvalidKeyException
(
"Missing password"
);
}
passwdChars
=
new
char
[
passwdBytes
.
length
];
for
(
int
i
=
0
;
i
<
passwdChars
.
length
;
i
++)
{
passwdChars
[
i
]
=
(
char
)
(
passwdBytes
[
i
]
&
0x7f
);
}
Arrays
.
fill
(
passwdBytes
,
(
byte
)
0x00
);
}
else
{
throw
new
InvalidKeyException
(
"SecretKey of PBE type required"
);
}
if
(((
opmode
==
Cipher
.
DECRYPT_MODE
)
||
(
opmode
==
Cipher
.
UNWRAP_MODE
))
&&
((
params
==
null
)
&&
((
salt
==
null
)
||
(
iCount
==
0
))))
{
throw
new
InvalidAlgorithmParameterException
(
"Parameters missing"
);
}
try
{
if
(((
opmode
==
Cipher
.
DECRYPT_MODE
)
||
(
opmode
==
Cipher
.
UNWRAP_MODE
))
&&
((
params
==
null
)
&&
((
salt
==
null
)
||
(
iCount
==
0
))))
{
throw
new
InvalidAlgorithmParameterException
(
"Parameters missing"
);
}
if
(
params
==
null
)
{
// generate default for salt and iteration count if necessary
if
(
salt
==
null
)
{
salt
=
new
byte
[
DEFAULT_SALT_LENGTH
];
if
(
random
!=
null
)
{
random
.
nextBytes
(
salt
);
if
(
params
==
null
)
{
// generate default for salt and iteration count if necessary
if
(
salt
==
null
)
{
salt
=
new
byte
[
DEFAULT_SALT_LENGTH
];
if
(
random
!=
null
)
{
random
.
nextBytes
(
salt
);
}
else
{
SunJCE
.
getRandom
().
nextBytes
(
salt
);
}
}
if
(
iCount
==
0
)
iCount
=
DEFAULT_COUNT
;
}
else
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec type required"
);
}
else
{
PBEParameterSpec
pbeParams
=
(
PBEParameterSpec
)
params
;
// make sure the parameter values are consistent
if
(
salt
!=
null
)
{
if
(!
Arrays
.
equals
(
salt
,
pbeParams
.
getSalt
()))
{
throw
new
InvalidAlgorithmParameterException
(
"Inconsistent value of salt between key and params"
);
}
}
else
{
SunJCE
.
getRandom
().
nextBytes
(
salt
);
salt
=
pbeParams
.
getSalt
(
);
}
}
if
(
iCount
==
0
)
iCount
=
DEFAULT_COUNT
;
}
else
if
(!(
params
instanceof
PBEParameterSpec
))
{
throw
new
InvalidAlgorithmParameterException
(
"PBEParameterSpec type required"
);
}
else
{
PBEParameterSpec
pbeParams
=
(
PBEParameterSpec
)
params
;
// make sure the parameter values are consistent
if
(
salt
!=
null
)
{
if
(!
Arrays
.
equals
(
salt
,
pbeParams
.
getSalt
()))
{
throw
new
InvalidAlgorithmParameterException
(
"Inconsistent value of salt between key and params"
);
if
(
iCount
!=
0
)
{
if
(
iCount
!=
pbeParams
.
getIterationCount
())
{
throw
new
InvalidAlgorithmParameterException
(
"Different iteration count between key and params"
);
}
}
else
{
iCount
=
pbeParams
.
getIterationCount
();
}
}
else
{
salt
=
pbeParams
.
getSalt
();
}
if
(
iCount
!=
0
)
{
if
(
iCount
!=
pbeParams
.
getIterationCount
())
{
throw
new
InvalidAlgorithmParameterException
(
"Different iteration count between key and params"
);
}
}
else
{
iCount
=
pbeParams
.
getIterationCount
();
// salt is recommended to be ideally as long as the output
// of the hash function. However, it may be too strict to
// force this; so instead, we'll just require the minimum
// salt length to be 8-byte which is what PKCS#5 recommends
// and openssl does.
if
(
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
}
// salt is recommended to be ideally as long as the output
// of the hash function. However, it may be too strict to
// force this; so instead, we'll just require the minimum
// salt length to be 8-byte which is what PKCS#5 recommends
// and openssl does.
if
(
salt
.
length
<
8
)
{
throw
new
InvalidAlgorithmParameterException
(
"Salt must be at least 8 bytes long"
);
}
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
}
byte
[]
derivedKey
=
derive
(
passwdChars
,
salt
,
iCount
,
keySize
,
CIPHER_KEY
);
SecretKey
cipherKey
=
new
SecretKeySpec
(
derivedKey
,
algo
);
if
(
iCount
<=
0
)
{
throw
new
InvalidAlgorithmParameterException
(
"IterationCount must be a positive number"
);
}
byte
[]
derivedKey
=
derive
(
passwdChars
,
salt
,
iCount
,
keySize
,
CIPHER_KEY
);
SecretKey
cipherKey
=
new
SecretKeySpec
(
derivedKey
,
algo
);
if
(
cipherImpl
!=
null
&&
cipherImpl
instanceof
ARCFOURCipher
)
{
((
ARCFOURCipher
)
cipherImpl
).
engineInit
(
opmode
,
cipherKey
,
random
);
if
(
cipherImpl
!=
null
&&
cipherImpl
instanceof
ARCFOURCipher
)
{
((
ARCFOURCipher
)
cipherImpl
).
engineInit
(
opmode
,
cipherKey
,
random
);
}
else
{
byte
[]
derivedIv
=
derive
(
passwdChars
,
salt
,
iCount
,
8
,
CIPHER_IV
);
IvParameterSpec
ivSpec
=
new
IvParameterSpec
(
derivedIv
,
0
,
8
);
}
else
{
byte
[]
derivedIv
=
derive
(
passwdChars
,
salt
,
iCount
,
8
,
CIPHER_IV
);
IvParameterSpec
ivSpec
=
new
IvParameterSpec
(
derivedIv
,
0
,
8
);
// initialize the underlying cipher
cipher
.
init
(
opmode
,
cipherKey
,
ivSpec
,
random
);
// initialize the underlying cipher
cipher
.
init
(
opmode
,
cipherKey
,
ivSpec
,
random
);
}
}
finally
{
Arrays
.
fill
(
passwdChars
,
'\0'
);
}
}
...
...
src/share/classes/sun/security/provider/DigestBase.java
浏览文件 @
0bc93426
...
...
@@ -28,6 +28,7 @@ package sun.security.provider;
import
java.security.MessageDigestSpi
;
import
java.security.DigestException
;
import
java.security.ProviderException
;
import
java.util.Arrays
;
/**
* Common base message digest implementation for the Sun provider.
...
...
@@ -151,6 +152,7 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
implReset
();
bufOfs
=
0
;
bytesProcessed
=
0
;
Arrays
.
fill
(
buffer
,
(
byte
)
0x00
);
}
// return the digest. See JCA doc.
...
...
src/share/classes/sun/security/provider/MD4.java
浏览文件 @
0bc93426
...
...
@@ -26,6 +26,7 @@
package
sun.security.provider
;
import
java.security.*
;
import
java.util.Arrays
;
import
static
sun
.
security
.
provider
.
ByteArrayAccess
.*;
...
...
@@ -90,7 +91,7 @@ public final class MD4 extends DigestBase {
super
(
"MD4"
,
16
,
64
);
state
=
new
int
[
4
];
x
=
new
int
[
16
];
implReset
();
resetHashes
();
}
// clone this object
...
...
@@ -106,6 +107,12 @@ public final class MD4 extends DigestBase {
*/
void
implReset
()
{
// Load magic initialization constants.
resetHashes
();
// clear out old data
Arrays
.
fill
(
x
,
0
);
}
private
void
resetHashes
()
{
state
[
0
]
=
0x67452301
;
state
[
1
]
=
0xefcdab89
;
state
[
2
]
=
0x98badcfe
;
...
...
src/share/classes/sun/security/provider/MD5.java
浏览文件 @
0bc93426
...
...
@@ -25,6 +25,8 @@
package
sun.security.provider
;
import
java.util.Arrays
;
import
static
sun
.
security
.
provider
.
ByteArrayAccess
.*;
/**
...
...
@@ -66,7 +68,7 @@ public final class MD5 extends DigestBase {
super
(
"MD5"
,
16
,
64
);
state
=
new
int
[
4
];
x
=
new
int
[
16
];
implReset
();
resetHashes
();
}
// clone this object
...
...
@@ -82,6 +84,12 @@ public final class MD5 extends DigestBase {
*/
void
implReset
()
{
// Load magic initialization constants.
resetHashes
();
// clear out old data
Arrays
.
fill
(
x
,
0
);
}
private
void
resetHashes
()
{
state
[
0
]
=
0x67452301
;
state
[
1
]
=
0xefcdab89
;
state
[
2
]
=
0x98badcfe
;
...
...
src/share/classes/sun/security/provider/SHA.java
浏览文件 @
0bc93426
...
...
@@ -25,6 +25,8 @@
package
sun.security.provider
;
import
java.util.Arrays
;
import
static
sun
.
security
.
provider
.
ByteArrayAccess
.*;
/**
...
...
@@ -59,7 +61,7 @@ public final class SHA extends DigestBase {
super
(
"SHA-1"
,
20
,
64
);
state
=
new
int
[
5
];
W
=
new
int
[
80
];
implReset
();
resetHashes
();
}
/*
...
...
@@ -76,6 +78,13 @@ public final class SHA extends DigestBase {
* Resets the buffers and hash value to start a new hash.
*/
void
implReset
()
{
// Load magic initialization constants.
resetHashes
();
// clear out old data
Arrays
.
fill
(
W
,
0
);
}
private
void
resetHashes
()
{
state
[
0
]
=
0x67452301
;
state
[
1
]
=
0xefcdab89
;
state
[
2
]
=
0x98badcfe
;
...
...
src/share/classes/sun/security/provider/SHA2.java
浏览文件 @
0bc93426
...
...
@@ -25,6 +25,8 @@
package
sun.security.provider
;
import
java.util.Arrays
;
import
static
sun
.
security
.
provider
.
ByteArrayAccess
.*;
/**
...
...
@@ -80,13 +82,18 @@ abstract class SHA2 extends DigestBase {
this
.
initialHashes
=
initialHashes
;
state
=
new
int
[
8
];
W
=
new
int
[
64
];
implReset
();
resetHashes
();
}
/**
* Resets the buffers and hash value to start a new hash.
*/
void
implReset
()
{
resetHashes
();
Arrays
.
fill
(
W
,
0
);
}
private
void
resetHashes
()
{
System
.
arraycopy
(
initialHashes
,
0
,
state
,
0
,
state
.
length
);
}
...
...
src/share/classes/sun/security/provider/SHA5.java
浏览文件 @
0bc93426
...
...
@@ -25,8 +25,7 @@
package
sun.security.provider
;
import
java.security.*
;
import
java.math.BigInteger
;
import
java.util.Arrays
;
import
static
sun
.
security
.
provider
.
ByteArrayAccess
.*;
...
...
@@ -98,10 +97,15 @@ abstract class SHA5 extends DigestBase {
this
.
initialHashes
=
initialHashes
;
state
=
new
long
[
8
];
W
=
new
long
[
80
];
implReset
();
resetHashes
();
}
final
void
implReset
()
{
resetHashes
();
Arrays
.
fill
(
W
,
0L
);
}
private
void
resetHashes
()
{
System
.
arraycopy
(
initialHashes
,
0
,
state
,
0
,
state
.
length
);
}
...
...
test/com/sun/crypto/provider/Cipher/PBE/PKCS12Cipher.java
浏览文件 @
0bc93426
...
...
@@ -105,7 +105,7 @@ class MyPBEKey implements PBEKey {
this
.
salt
=
salt
;
this
.
iCount
=
iCount
;
}
public
char
[]
getPassword
()
{
return
passwd
;
}
public
char
[]
getPassword
()
{
return
passwd
.
clone
()
;
}
public
byte
[]
getSalt
()
{
return
salt
;
}
public
int
getIterationCount
()
{
return
iCount
;
}
public
String
getAlgorithm
()
{
return
"PBE"
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录