|
DES1KeySpec |
|
1 /* $RCSfile: DES1KeySpec.java,v $ 2 * $Revision: 1.10 $ 3 * $Date: 2002/11/23 11:09:57 $ 4 * $Author: uwe_guenther $ 5 * $State: Exp $ 6 * 7 * Created on August 11, 2001 11:18 AM 8 * 9 * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de> 10 * 11 * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE- 12 * ServiceProvider is a library, written in JavaTM, that should be 13 * used in HBCI banking applications (clients and may be servers), 14 * to do cryptographic operations. 15 * 16 * The jhbci library is free software; you can redistribute it and/or 17 * modify it under the terms of the GNU Lesser General Public 18 * License as published by the Free Software Foundation; either 19 * version 2.1 of the License, or (at your option) any later version. 20 * 21 * The jhbci library is distributed in the hope that it will be useful, 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 * Lesser General Public License for more details. 25 * 26 * You should have received a copy of the GNU Lesser General Public 27 * License along with this library; if not, write to the Free Software 28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29 * 30 */ 31 32 package de.cscc.crypto.provider.spec; 33 34 import java.security.InvalidKeyException; 35 import java.util.Arrays; 36 37 import de.cscc.crypto.util.ByteUtil; 38 39 /** 40 * DES secret key specification (56 bit or 64 bit with parity) class. 41 * 42 * <p>This class is immutable. 43 * 44 * @author <a href=mailto:uwe@cscc.de>Uwe Günther</a> 45 * @version $Revision: 1.10 $ 46 */ 47 public class DES1KeySpec implements DESKeySpec, Cloneable { 48 49 /** Key length in bytes. */ 50 private static final int DES_KEY_LEN = 8; 51 52 /** The 4 DES weak keys. */ 53 private static final byte[][] WEAK_KEYS = { 54 //weak key 0 55 { 56 (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, 57 (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01 58 }, 59 60 //weak key 1 61 { 62 (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, 63 (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe 64 }, 65 66 //weak key 2 67 { 68 (byte)0x1f, (byte)0x1f, (byte)0x1f, (byte)0x1f, 69 (byte)0x0e, (byte)0x0e, (byte)0x0e, (byte)0x0e 70 }, 71 72 //weak key 3 73 { 74 (byte)0xe0, (byte)0xe0, (byte)0xe0, (byte)0xe0, 75 (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf1 76 } 77 }; 78 79 /** The 12 DES semi weak keys. */ 80 private static final byte[][] SEMI_WEAK_KEYS = { 81 //semi weak key 0 82 { 83 (byte)0x01, (byte)0xfe, (byte)0x01, (byte)0xfe, 84 (byte)0x01, (byte)0xfe, (byte)0x01, (byte)0xfe 85 }, 86 87 //semi weak key 1 88 { 89 (byte)0xfe, (byte)0x01, (byte)0xfe, (byte)0x01, 90 (byte)0xfe, (byte)0x01, (byte)0xfe, (byte)0x01 91 }, 92 93 //semi weak key 2 94 { 95 (byte)0x1f, (byte)0xe0, (byte)0x1f, (byte)0xe0, 96 (byte)0x0e, (byte)0xf1, (byte)0x0e, (byte)0xf1 97 }, 98 99 //semi weak key 3 100 { 101 (byte)0xe0, (byte)0x1f, (byte)0xe0, (byte)0x1f, 102 (byte)0xf1, (byte)0x0e, (byte)0xf1, (byte)0x0e 103 }, 104 105 //semi weak key 4 106 { 107 (byte)0x01, (byte)0xe0, (byte)0x01, (byte)0xe0, 108 (byte)0x01, (byte)0xf1, (byte)0x01, (byte)0xf1 109 }, 110 111 //semi weak key 5 112 { 113 (byte)0xe0, (byte)0x01, (byte)0xe0, (byte)0x01, 114 (byte)0xf1, (byte)0x01, (byte)0xf1, (byte)0x01 115 }, 116 117 //semi weak key 6 118 { 119 (byte)0x1f, (byte)0xfe, (byte)0x1f, (byte)0xfe, 120 (byte)0x0e, (byte)0xfe, (byte)0x0e, (byte)0xfe 121 }, 122 123 //semi weak key 7 124 { 125 (byte)0xfe, (byte)0x1f, (byte)0xfe, (byte)0x1f, 126 (byte)0xfe, (byte)0x0e, (byte)0xfe, (byte)0x0e 127 }, 128 129 //semi weak key 8 130 { 131 (byte)0x01, (byte)0x1f, (byte)0x01, (byte)0x1f, 132 (byte)0x01, (byte)0x0e, (byte)0x01, (byte)0x0e 133 }, 134 135 //semi weak key 9 136 { 137 (byte)0x1f, (byte)0x01, (byte)0x1f, (byte)0x01, 138 (byte)0x0e, (byte)0x01, (byte)0x0e, (byte)0x01 139 }, 140 141 //semi weak key 10 142 { 143 (byte)0xe0, (byte)0xfe, (byte)0xe0, (byte)0xfe, 144 (byte)0xf1, (byte)0xfe, (byte)0xf1, (byte)0xfe 145 }, 146 147 //semi weak key 11 148 { 149 (byte)0xfe, (byte)0xe0, (byte)0xfe, (byte)0xe0, 150 (byte)0xfe, (byte)0xf1, (byte)0xfe, (byte)0xf1 151 } 152 153 }; 154 155 /** Internal data representation. */ 156 private byte[] key = new byte[8]; 157 158 /** 159 * Creates a new DES1KeySpec from a 16 bytes long byte array. We 160 * use the first 8 bytes in key as the key material for the DES key. 161 * The bytes that constitute the two DES keys are those between 162 * key[0] and key[8] inclusive. 163 * 164 * @param key the buffer with the DES keys. 165 * @throws InvalidKeyException if the given key material is shorter 166 * than 8 bytes or the key is weak or semi weak. 167 */ 168 public DES1KeySpec(byte[] key) throws InvalidKeyException { 169 this(key, 0); 170 } 171 172 /** 173 * Creates a new DES1KeySpec from a 16 bytes long byte array. 174 * 175 * @param key the buffer with the DES keys. 176 * @param offset the offset in key, where the key starts. 177 * @throws InvalidKeyException if the given key material is shorter 178 * than 8 bytes or the key is weak or semi weak. 179 */ 180 public DES1KeySpec(byte[] key, int offset) throws InvalidKeyException { 181 if(key.length-offset < 8){ 182 throw new InvalidKeyException( 183 "Usable byte range is " + (key.length-offset) + 184 " bytes large, but it should be 8 bytes or larger."); 185 } 186 187 System.arraycopy(key, offset, this.key, 0, 8); 188 189 //We have to first adjust the parity, 190 //because isWeak() and isSemiWeak() does deliver wrong results. 191 if (isParityAdjusted() == false){ 192 adjustParity(); 193 } 194 195 //After parity adjusting, now we can test if the key is weak. 196 if (isWeak() == true){ 197 throw new InvalidKeyException( 198 "Key " + toString() + " is on of 4 weak DES keys."); 199 } 200 201 //After parity adjusting, now we can test if the key is semi weak. 202 if (isSemiWeak() == true){ 203 throw new InvalidKeyException( 204 "Key " + toString() + " is on of 12 semi weak DES keys."); 205 } 206 } 207 208 /** 209 * Creates a new DES1KeySpec from an existing one. 210 * 211 * @param key DesKeySpec object with a key. 212 */ 213 public DES1KeySpec(DES1KeySpec key) { 214 System.arraycopy(key.key, 0, this.key, 0, 8); 215 } 216 217 /** 218 * Creates and returns a deep copy of this object. 219 * 220 * @return a clone of this instance. 221 * @see java.lang.Cloneable 222 * @exception CloneNotSupportedException if the object's class does not 223 * support the <code>Cloneable</code> interface. Subclasses 224 * that override the <code>clone</code> method can also 225 * throw this exception to indicate that an instance cannot 226 * be cloned. 227 */ 228 public Object clone() throws CloneNotSupportedException { 229 DES1KeySpec result = (DES1KeySpec) super.clone(); 230 result.key = (byte[]) this.key.clone(); 231 return result; 232 } 233 234 /** 235 * Indicates whether some other object is "equal to" this one. 236 * 237 * @param obj the reference object with which to compare. 238 * @return <code>true</code> if this object is the same as the obj 239 * argument; <code>false</code> otherwise. 240 * @see #hashCode() 241 * @see java.util.Hashtable 242 */ 243 public boolean equals(Object obj) { 244 //Only for performance. 245 if (this == obj) { 246 return true; 247 } 248 249 //If obj == null then instanceof returns false, see JLS 15.20.2 250 if (!(obj instanceof DES1KeySpec)) { 251 return false; 252 } 253 254 DES1KeySpec other = (DES1KeySpec)obj; 255 return Arrays.equals(this.key, other.key); 256 } 257 258 /** 259 * Returns a hash code value for the object. This method is 260 * supported for the benefit of hashtables such as those provided by 261 * <code>java.util.Hashtable</code>. 262 * 263 * @return a hash code value for this object. 264 * @see #equals(java.lang.Object) 265 * @see java.util.Hashtable 266 */ 267 public int hashCode() { 268 int result = 17; 269 for(int i = 0; i < this.key.length; i++) { 270 result = 37*result + this.key[i]; 271 } 272 return result; 273 } 274 275 /** 276 * Returns a string representation of the object. 277 * 278 * @return a string representation of the object. 279 */ 280 public String toString() { 281 return ByteUtil.toHex(this.key); 282 } 283 284 /** 285 * Resets the internal data representation to 0 (zero). 286 * 287 * Only for security reasons. 288 */ 289 private void reset() { 290 Arrays.fill(this.key, (byte) 0x00); 291 } 292 293 /** 294 * Get the DES Key as byte[8]. 295 * 296 * @return the DES Key as byte[8]. 297 */ 298 public byte[] getKey() { 299 /*byte[] returnValue =new byte[8]; 300 System.arraycopy(this.key, 0, returnValue, 0, 8); 301 return returnValue;*/ 302 return (byte[]) this.key.clone(); 303 } 304 305 /** 306 * Checks parity for the whole key. 307 * 308 * @return true if the whole key is parity adjusted, respectively all 309 * bytes have odd parity, or false otherwise. 310 */ 311 private boolean isParityAdjusted() { 312 for (int i = 0; i < this.key.length; i++) { 313 if (isParrityOdd(this.key[i]) == false) { 314 315 //At least one byte int the key 316 //has even parity and is corrupted. 317 return false; 318 } 319 } 320 321 //All bytes in the key has odd parity 322 //We say the key is parity adjusted. 323 return true; 324 } 325 326 /** 327 * Checks parity of a byte. 328 * 329 * The right most bit used as placeholder to change the parity. 330 * 331 * 00000010 -> odd parity 332 * 00000110 -> even parity 333 * 00001110 -> odd parity 334 * . 335 * . 336 * 10001110 -> even parity 337 * 338 * @return true if the parity of byte b is odd, or false if the parity is even. 339 * @param b the byte to check. 340 */ 341 private boolean isParrityOdd(byte b) { 342 343 if ((( 344 (b >>> 0) ^ 345 (b >>> 1) ^ 346 (b >>> 2) ^ 347 (b >>> 3) ^ 348 (b >>> 4) ^ 349 (b >>> 5) ^ 350 (b >>> 6) ^ 351 (b >>> 7) 352 ) & 0x00000001 ) == 0x00000001) 353 { 354 return true; //1 355 } else { 356 return false; //0 357 } 358 } 359 360 /** 361 * Adjust the parity to odd parity (means a odd sum of "1" bits). 362 * 363 * The right most bit (bit 8) in every byte in the DES key is the 364 * parity bit. Every byte in the DES key must have always odd parity! 365 * If one byte in the key has not odd parity, the key is corrupted. 366 */ 367 private void adjustParity() { 368 for (int i = 0; i < 8; i++){ 369 this.key[i] = oddParity(this.key[i]); 370 } 371 } 372 373 /** 374 * Sets a byte b to odd parity, if it has even parity. 375 * If the input byte b has odd parity the return value will be 376 * the same as the input value b. 377 * 378 * <pre> 379 * 00000010 -> odd parity 380 * 00000110 -> even parity 381 * 00001110 -> odd parity 382 * . 383 * . 384 * 10001110 -> even parity 385 * </pre> 386 * 387 * Even parity means that the number of all "1" bits are even. 388 * Odd parity means that the number of all "1" bits are odd. 389 * 390 * The algorithm works in the following way: 391 * The right most bit (bit 8) is the parity bit. 392 * Every byte in the DES key must have always odd parity! 393 * If one byte in the key has not odd parity, the key is corrupted. 394 * 395 * That means: 396 * Is the sum of all "1" bits from bit 1 to bit 7 odd, set bit 8 to "0". 397 * IS the sum of all "1" bits from bit 1 to bit 7 even, set bit 8 to "1". 398 * 399 * @param b the byte where will be set to odd parity. 400 * @return the parity adjusted byte. 401 */ 402 private byte oddParity(byte b) { 403 return (byte)( 404 (b & 0x000000fe) | ( //set bit 8 to 0 405 ( 406 ( 407 //xor bit 1 to 7 408 (b >>> 1) ^ 409 (b >>> 2) ^ 410 (b >>> 3) ^ 411 (b >>> 4) ^ 412 (b >>> 5) ^ 413 (b >>> 6) ^ 414 (b >>> 7) 415 416 //delete bit 1 to bit 7 417 ) & 0x00000001 418 419 //if the xor result "0" means even 420 //set party bit to "1" means odd 421 // 422 //if the xor result "1" means odd 423 //set parity bit to "0" means odd 424 ) ^ 0x00000001 425 ) 426 ); 427 } 428 429 /** 430 * Returns true, if the internal data representation of the key is 431 * equal with one of the 4 weak keys. 432 * 433 * @return true if the key is weak, false otherwise. 434 */ 435 private boolean isWeak() { 436 for (int i = 0; i < 4; i++) { 437 if (Arrays.equals(DES1KeySpec.WEAK_KEYS[i], this.key)) { 438 return true; 439 } 440 } 441 442 return false; 443 } 444 445 /** 446 * Returns true, if the internal data representation of the key is 447 * equal with one of the 12 semi weak keys. 448 * 449 * @return true if the key is semi weak, false otherwise. 450 */ 451 private boolean isSemiWeak() { 452 for (int i = 0; i < 12; i++){ 453 if (Arrays.equals(DES1KeySpec.SEMI_WEAK_KEYS[i], this.key)) { 454 return true; 455 } 456 } 457 458 return false; 459 } 460 } 461
|
DES1KeySpec |
|