001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.util.crypto.params; 019 020 public class DESParameters 021 extends KeyParameter 022 { 023 public DESParameters( 024 byte[] key) 025 { 026 super(key); 027 028 if (isWeakKey(key, 0)) 029 { 030 throw new IllegalArgumentException("attempt to create weak DES key"); 031 } 032 } 033 034 /* 035 * DES Key length in bytes. 036 */ 037 static public final int DES_KEY_LENGTH = 8; 038 039 /* 040 * Table of weak and semi-weak keys taken from Schneier pp281 041 */ 042 static private final int N_DES_WEAK_KEYS = 16; 043 044 static private byte[] DES_weak_keys = 045 { 046 /* weak keys */ 047 (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, 048 (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, 049 (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, 050 (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, 051 052 /* semi-weak keys */ 053 (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, 054 (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, 055 (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, 056 (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, 057 (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, 058 (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, 059 (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, 060 (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, 061 (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, 062 (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, 063 (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, 064 (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 065 }; 066 067 /** 068 * DES has 16 weak keys. This method will check 069 * if the given DES key material is weak or semi-weak. 070 * Key material that is too short is regarded as weak. 071 * <p> 072 * See <a href="http://www.counterpane.com/applied.html">"Applied 073 * Cryptography"</a> by Bruce Schneier for more information. 074 * 075 * @return true if the given DES key material is weak or semi-weak, 076 * false otherwise. 077 */ 078 public static boolean isWeakKey( 079 byte[] key, 080 int offset) 081 { 082 if (key.length - offset < DES_KEY_LENGTH) 083 { 084 throw new IllegalArgumentException("key material too short."); 085 } 086 087 nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++) 088 { 089 for (int j = 0; j < DES_KEY_LENGTH; j++) 090 { 091 if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j]) 092 { 093 continue nextkey; 094 } 095 } 096 097 return true; 098 } 099 return false; 100 } 101 102 /** 103 * DES Keys use the LSB as the odd parity bit. This can 104 * be used to check for corrupt keys. 105 * 106 * @param bytes the byte array to set the parity on. 107 */ 108 public static void setOddParity( 109 byte[] bytes) 110 { 111 for (int i = 0; i < bytes.length; i++) 112 { 113 int b = bytes[i]; 114 bytes[i] = (byte)((b & 0xfe) | 115 ((((b >> 1) ^ 116 (b >> 2) ^ 117 (b >> 3) ^ 118 (b >> 4) ^ 119 (b >> 5) ^ 120 (b >> 6) ^ 121 (b >> 7)) ^ 0x01) & 0x01)); 122 } 123 } 124 }