using System; namespace Org.BouncyCastle.Crypto.Parameters { public class DesParameters : KeyParameter { public DesParameters( byte[] key) : base(key) { if (IsWeakKey(key)) throw new ArgumentException("attempt to create weak DES key"); } public DesParameters( byte[] key, int keyOff, int keyLen) : base(key, keyOff, keyLen) { if (IsWeakKey(key, keyOff)) throw new ArgumentException("attempt to create weak DES key"); } /* * DES Key Length in bytes. */ public const int DesKeyLength = 8; /* * Table of weak and semi-weak keys taken from Schneier pp281 */ private const int N_DES_WEAK_KEYS = 16; private static readonly byte[] DES_weak_keys = { /* weak keys */ (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, /* semi-weak keys */ (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 }; /** * DES has 16 weak keys. This method will check * if the given DES key material is weak or semi-weak. * Key material that is too short is regarded as weak. *
* See "Applied * Cryptography" by Bruce Schneier for more information. *
* @return true if the given DES key material is weak or semi-weak, * false otherwise. */ public static bool IsWeakKey( byte[] key, int offset) { if (key.Length - offset < DesKeyLength) throw new ArgumentException("key material too short."); //nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++) { bool unmatch = false; for (int j = 0; j < DesKeyLength; j++) { if (key[j + offset] != DES_weak_keys[i * DesKeyLength + j]) { //continue nextkey; unmatch = true; break; } } if (!unmatch) { return true; } } return false; } public static bool IsWeakKey( byte[] key) { return IsWeakKey(key, 0); } /** * 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) { 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)); } } } }