diff --git a/crypto/src/crypto/generators/DesEdeKeyGenerator.cs b/crypto/src/crypto/generators/DesEdeKeyGenerator.cs
index 5902643fd..904cc71f1 100644
--- a/crypto/src/crypto/generators/DesEdeKeyGenerator.cs
+++ b/crypto/src/crypto/generators/DesEdeKeyGenerator.cs
@@ -52,14 +52,14 @@ namespace Org.BouncyCastle.Crypto.Generators
protected override byte[] engineGenerateKey()
{
- byte[] newKey;
+ byte[] newKey = new byte[strength];
- do
+ do
{
- newKey = random.GenerateSeed(strength);
+ random.NextBytes(newKey);
DesEdeParameters.SetOddParity(newKey);
}
- while (DesEdeParameters.IsWeakKey(newKey, 0, newKey.Length));
+ while (DesEdeParameters.IsWeakKey(newKey, 0, newKey.Length) || !DesEdeParameters.IsRealEdeKey(newKey, 0));
return newKey;
}
diff --git a/crypto/src/crypto/generators/DesKeyGenerator.cs b/crypto/src/crypto/generators/DesKeyGenerator.cs
index 154e3471a..4c2051d89 100644
--- a/crypto/src/crypto/generators/DesKeyGenerator.cs
+++ b/crypto/src/crypto/generators/DesKeyGenerator.cs
@@ -42,12 +42,12 @@ namespace Org.BouncyCastle.Crypto.Generators
protected override byte[] engineGenerateKey()
{
- byte[] newKey;
+ byte[] newKey = new byte[DesParameters.DesKeyLength];
- do
+ do
{
- newKey = random.GenerateSeed(DesParameters.DesKeyLength);
- DesParameters.SetOddParity(newKey);
+ random.NextBytes(newKey);
+ DesParameters.SetOddParity(newKey);
}
while (DesParameters.IsWeakKey(newKey, 0));
diff --git a/crypto/src/crypto/parameters/DesEdeParameters.cs b/crypto/src/crypto/parameters/DesEdeParameters.cs
index 420aaecea..6be56fb2c 100644
--- a/crypto/src/crypto/parameters/DesEdeParameters.cs
+++ b/crypto/src/crypto/parameters/DesEdeParameters.cs
@@ -91,5 +91,50 @@ namespace Org.BouncyCastle.Crypto.Parameters
{
return IsWeakKey(key, 0, key.Length);
}
+
+ /**
+ * return true if the passed in key is a real 2/3 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static bool IsRealEdeKey(byte[] key, int offset)
+ {
+ return key.Length == 16 ? IsReal2Key(key, offset) : IsReal3Key(key, offset);
+ }
+
+ /**
+ * return true if the passed in key is a real 2 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static bool IsReal2Key(byte[] key, int offset)
+ {
+ bool isValid = false;
+ for (int i = offset; i != offset + 8; i++)
+ {
+ isValid |= (key[i] != key[i + 8]);
+ }
+ return isValid;
+ }
+
+ /**
+ * return true if the passed in key is a real 3 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static bool IsReal3Key(byte[] key, int offset)
+ {
+ bool diff12 = false, diff13 = false, diff23 = false;
+ for (int i = offset; i != offset + 8; i++)
+ {
+ diff12 |= (key[i] != key[i + 8]);
+ diff13 |= (key[i] != key[i + 16]);
+ diff23 |= (key[i + 8] != key[i + 16]);
+ }
+ return diff12 && diff13 && diff23;
+ }
}
}
diff --git a/crypto/src/crypto/parameters/DesParameters.cs b/crypto/src/crypto/parameters/DesParameters.cs
index ee37cd861..a1f67e2b1 100644
--- a/crypto/src/crypto/parameters/DesParameters.cs
+++ b/crypto/src/crypto/parameters/DesParameters.cs
@@ -103,28 +103,37 @@ namespace Org.BouncyCastle.Crypto.Parameters
return IsWeakKey(key, 0);
}
- /**
+ public static byte SetOddParity(byte b)
+ {
+ uint parity = b ^ 1U;
+ parity ^= (parity >> 4);
+ parity ^= (parity >> 2);
+ parity ^= (parity >> 1);
+ parity &= 1U;
+
+ return (byte)(b ^ parity);
+ }
+
+ /**
* DES Keys use the LSB as the odd parity bit. This can
* be used to check for corrupt keys.
*
* @param bytes the byte array to set the parity on.
*/
- public static void SetOddParity(
- byte[] bytes)
+ public static void SetOddParity(byte[] bytes)
{
for (int i = 0; i < bytes.Length; i++)
{
- int b = bytes[i];
- bytes[i] = (byte)((b & 0xfe) |
- ((((b >> 1) ^
- (b >> 2) ^
- (b >> 3) ^
- (b >> 4) ^
- (b >> 5) ^
- (b >> 6) ^
- (b >> 7)) ^ 0x01) & 0x01));
+ bytes[i] = SetOddParity(bytes[i]);
}
}
- }
+ public static void SetOddParity(byte[] bytes, int off, int len)
+ {
+ for (int i = 0; i < len; i++)
+ {
+ bytes[off + i] = SetOddParity(bytes[off + i]);
+ }
+ }
+ }
}
diff --git a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
index 2e4fbe4ed..eca1821d3 100644
--- a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
@@ -460,18 +460,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
tmp[tmpOff + 6] = (byte)((keyMaster[keyOff + 5] << 2) | ((keyMaster[keyOff + 6] & 0x80) >> 6));
tmp[tmpOff + 7] = (byte)(keyMaster[keyOff + 6] << 1);
- for (int i = tmpOff; i <= tmpOff + 7; i++)
- {
- uint b = tmp[i];
-
- uint parity = b ^ 1U;
- parity ^= (parity >> 4);
- parity ^= (parity >> 2);
- parity ^= (parity >> 1);
- parity &= 1U;
-
- tmp[i] = (byte)(b ^ parity);
- }
+ DesParameters.SetOddParity(tmp, tmpOff, 8);
}
}
}
|