From 7fc458b7be71111b4c4a6e91f7b3ed6642b104a1 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Tue, 16 Jul 2013 14:12:20 +0000
Subject: [PATCH] CR-2005 Fix OPENDJ-1036 Cleanup passwords in memory?
---
opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java | 57 ++++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java
index 37dbf7c..6c7b98a 100644
--- a/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java
@@ -177,9 +177,10 @@
public ByteString encodePassword(ByteSequence plaintext)
throws DirectoryException
{
- byte[] saltBytes = new byte[NUM_SALT_BYTES];
+ byte[] saltBytes = new byte[NUM_SALT_BYTES];
byte[] digestBytes;
- int iterations = config.getPBKDF2Iterations();
+ char[] plaintextChars = null;
+ int iterations = config.getPBKDF2Iterations();
synchronized(factoryLock)
{
@@ -187,7 +188,8 @@
{
random.nextBytes(saltBytes);
- KeySpec spec = new PBEKeySpec(plaintext.toString().toCharArray(),
+ plaintextChars = plaintext.toString().toCharArray();
+ KeySpec spec = new PBEKeySpec(plaintextChars,
saltBytes, iterations, SHA1_LENGTH * 8);
digestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -203,6 +205,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
@@ -304,13 +311,15 @@
saltLength);
byte[] userDigestBytes;
+ char[] plaintextChars = null;
synchronized (factoryLock)
{
try
{
+ plaintextChars = plaintextPassword.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- plaintextPassword.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
userDigestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -323,6 +332,11 @@
return false;
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -360,9 +374,10 @@
public ByteString encodeAuthPassword(ByteSequence plaintext)
throws DirectoryException
{
- byte[] saltBytes = new byte[NUM_SALT_BYTES];
+ byte[] saltBytes = new byte[NUM_SALT_BYTES];
byte[] digestBytes;
- int iterations = config.getPBKDF2Iterations();
+ char[] plaintextChars = null;
+ int iterations = config.getPBKDF2Iterations();
synchronized(factoryLock)
{
@@ -370,8 +385,9 @@
{
random.nextBytes(saltBytes);
+ plaintextChars = plaintext.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- plaintext.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
digestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -387,6 +403,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
// Encode and return the value.
StringBuilder authPWValue = new StringBuilder();
@@ -446,13 +467,15 @@
saltBytes.length);
byte[] userDigestBytes;
+ char[] plaintextChars = null;
synchronized (factoryLock)
{
try
{
+ plaintextChars = plaintextPassword.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- plaintextPassword.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
userDigestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -465,6 +488,11 @@
return false;
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -540,16 +568,18 @@
public static String encodeOffline(byte[] passwordBytes)
throws DirectoryException
{
- byte[] saltBytes = new byte[NUM_SALT_BYTES];
+ byte[] saltBytes = new byte[NUM_SALT_BYTES];
byte[] digestBytes;
- int iterations = 10000;
+ char[] plaintextChars = null;
+ int iterations = 10000;
try
{
SecureRandom.getInstance(SECURE_PRNG_SHA1).nextBytes(saltBytes);
+ plaintextChars = passwordBytes.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- passwordBytes.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
digestBytes = SecretKeyFactory
.getInstance(MESSAGE_DIGEST_ALGORITHM_PBKDF2)
@@ -567,6 +597,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
// Append the salt to the hashed value and base64-the whole thing.
byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
--
Gitblit v1.10.0