DES.java revision 53b61f9fe9d58034fcc7021137e92460f91b70ce
1package org.bouncycastle.jcajce.provider.symmetric; 2 3import java.security.AlgorithmParameters; 4import java.security.InvalidAlgorithmParameterException; 5import java.security.SecureRandom; 6import java.security.spec.AlgorithmParameterSpec; 7import java.security.spec.InvalidKeySpecException; 8import java.security.spec.KeySpec; 9 10import javax.crypto.SecretKey; 11import javax.crypto.spec.DESKeySpec; 12import javax.crypto.spec.IvParameterSpec; 13import javax.crypto.spec.PBEKeySpec; 14import javax.crypto.spec.SecretKeySpec; 15 16import org.bouncycastle.asn1.ASN1ObjectIdentifier; 17import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 18import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 19import org.bouncycastle.crypto.CipherParameters; 20import org.bouncycastle.crypto.KeyGenerationParameters; 21import org.bouncycastle.crypto.engines.DESEngine; 22import org.bouncycastle.crypto.engines.RFC3211WrapEngine; 23import org.bouncycastle.crypto.generators.DESKeyGenerator; 24import org.bouncycastle.crypto.macs.CBCBlockCipherMac; 25import org.bouncycastle.crypto.macs.CFBBlockCipherMac; 26import org.bouncycastle.crypto.macs.CMac; 27import org.bouncycastle.crypto.macs.ISO9797Alg3Mac; 28import org.bouncycastle.crypto.modes.CBCBlockCipher; 29import org.bouncycastle.crypto.paddings.ISO7816d4Padding; 30import org.bouncycastle.crypto.params.DESParameters; 31import org.bouncycastle.crypto.params.KeyParameter; 32import org.bouncycastle.crypto.params.ParametersWithIV; 33import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; 34import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; 35import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; 36import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; 37import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; 38import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; 39import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; 40import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; 41import org.bouncycastle.jcajce.provider.symmetric.util.PBE; 42import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; 43 44public final class DES 45{ 46 private DES() 47 { 48 } 49 50 static public class ECB 51 extends BaseBlockCipher 52 { 53 public ECB() 54 { 55 super(new DESEngine()); 56 } 57 } 58 59 static public class CBC 60 extends BaseBlockCipher 61 { 62 public CBC() 63 { 64 super(new CBCBlockCipher(new DESEngine()), 64); 65 } 66 } 67 68 /** 69 * DES CFB8 70 */ 71 public static class DESCFB8 72 extends BaseMac 73 { 74 public DESCFB8() 75 { 76 super(new CFBBlockCipherMac(new DESEngine())); 77 } 78 } 79 80 /** 81 * DES64 82 */ 83 public static class DES64 84 extends BaseMac 85 { 86 public DES64() 87 { 88 super(new CBCBlockCipherMac(new DESEngine(), 64)); 89 } 90 } 91 92 /** 93 * DES64with7816-4Padding 94 */ 95 public static class DES64with7816d4 96 extends BaseMac 97 { 98 public DES64with7816d4() 99 { 100 super(new CBCBlockCipherMac(new DESEngine(), 64, new ISO7816d4Padding())); 101 } 102 } 103 104 public static class CBCMAC 105 extends BaseMac 106 { 107 public CBCMAC() 108 { 109 super(new CBCBlockCipherMac(new DESEngine())); 110 } 111 } 112 113 static public class CMAC 114 extends BaseMac 115 { 116 public CMAC() 117 { 118 super(new CMac(new DESEngine())); 119 } 120 } 121 122 /** 123 * DES9797Alg3with7816-4Padding 124 */ 125 public static class DES9797Alg3with7816d4 126 extends BaseMac 127 { 128 public DES9797Alg3with7816d4() 129 { 130 super(new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding())); 131 } 132 } 133 134 /** 135 * DES9797Alg3 136 */ 137 public static class DES9797Alg3 138 extends BaseMac 139 { 140 public DES9797Alg3() 141 { 142 super(new ISO9797Alg3Mac(new DESEngine())); 143 } 144 } 145 146 public static class RFC3211 147 extends BaseWrapCipher 148 { 149 public RFC3211() 150 { 151 super(new RFC3211WrapEngine(new DESEngine()), 8); 152 } 153 } 154 155 public static class AlgParamGen 156 extends BaseAlgorithmParameterGenerator 157 { 158 protected void engineInit( 159 AlgorithmParameterSpec genParamSpec, 160 SecureRandom random) 161 throws InvalidAlgorithmParameterException 162 { 163 throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation."); 164 } 165 166 protected AlgorithmParameters engineGenerateParameters() 167 { 168 byte[] iv = new byte[8]; 169 170 if (random == null) 171 { 172 random = new SecureRandom(); 173 } 174 175 random.nextBytes(iv); 176 177 AlgorithmParameters params; 178 179 try 180 { 181 params = createParametersInstance("DES"); 182 params.init(new IvParameterSpec(iv)); 183 } 184 catch (Exception e) 185 { 186 throw new RuntimeException(e.getMessage()); 187 } 188 189 return params; 190 } 191 } 192 193 /** 194 * DES - the default for this is to generate a key in 195 * a-b-a format that's 24 bytes long but has 16 bytes of 196 * key material (the first 8 bytes is repeated as the last 197 * 8 bytes). If you give it a size, you'll get just what you 198 * asked for. 199 */ 200 public static class KeyGenerator 201 extends BaseKeyGenerator 202 { 203 public KeyGenerator() 204 { 205 super("DES", 64, new DESKeyGenerator()); 206 } 207 208 protected void engineInit( 209 int keySize, 210 SecureRandom random) 211 { 212 super.engineInit(keySize, random); 213 } 214 215 protected SecretKey engineGenerateKey() 216 { 217 if (uninitialised) 218 { 219 engine.init(new KeyGenerationParameters(new SecureRandom(), defaultKeySize)); 220 uninitialised = false; 221 } 222 223 return new SecretKeySpec(engine.generateKey(), algName); 224 } 225 } 226 227 static public class KeyFactory 228 extends BaseSecretKeyFactory 229 { 230 public KeyFactory() 231 { 232 super("DES", null); 233 } 234 235 protected KeySpec engineGetKeySpec( 236 SecretKey key, 237 Class keySpec) 238 throws InvalidKeySpecException 239 { 240 if (keySpec == null) 241 { 242 throw new InvalidKeySpecException("keySpec parameter is null"); 243 } 244 if (key == null) 245 { 246 throw new InvalidKeySpecException("key parameter is null"); 247 } 248 249 if (SecretKeySpec.class.isAssignableFrom(keySpec)) 250 { 251 return new SecretKeySpec(key.getEncoded(), algName); 252 } 253 else if (DESKeySpec.class.isAssignableFrom(keySpec)) 254 { 255 byte[] bytes = key.getEncoded(); 256 257 try 258 { 259 return new DESKeySpec(bytes); 260 } 261 catch (Exception e) 262 { 263 throw new InvalidKeySpecException(e.toString()); 264 } 265 } 266 267 throw new InvalidKeySpecException("Invalid KeySpec"); 268 } 269 270 protected SecretKey engineGenerateSecret( 271 KeySpec keySpec) 272 throws InvalidKeySpecException 273 { 274 if (keySpec instanceof DESKeySpec) 275 { 276 DESKeySpec desKeySpec = (DESKeySpec)keySpec; 277 return new SecretKeySpec(desKeySpec.getKey(), "DES"); 278 } 279 280 return super.engineGenerateSecret(keySpec); 281 } 282 } 283 284 static public class DESPBEKeyFactory 285 extends BaseSecretKeyFactory 286 { 287 private boolean forCipher; 288 private int scheme; 289 private int digest; 290 private int keySize; 291 private int ivSize; 292 293 public DESPBEKeyFactory( 294 String algorithm, 295 ASN1ObjectIdentifier oid, 296 boolean forCipher, 297 int scheme, 298 int digest, 299 int keySize, 300 int ivSize) 301 { 302 super(algorithm, oid); 303 304 this.forCipher = forCipher; 305 this.scheme = scheme; 306 this.digest = digest; 307 this.keySize = keySize; 308 this.ivSize = ivSize; 309 } 310 311 protected SecretKey engineGenerateSecret( 312 KeySpec keySpec) 313 throws InvalidKeySpecException 314 { 315 if (keySpec instanceof PBEKeySpec) 316 { 317 PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; 318 CipherParameters param; 319 320 if (pbeSpec.getSalt() == null) 321 { 322 return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null); 323 } 324 325 if (forCipher) 326 { 327 param = PBE.Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize); 328 } 329 else 330 { 331 param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize); 332 } 333 334 KeyParameter kParam; 335 if (param instanceof ParametersWithIV) 336 { 337 kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); 338 } 339 else 340 { 341 kParam = (KeyParameter)param; 342 } 343 344 DESParameters.setOddParity(kParam.getKey()); 345 346 return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param); 347 } 348 349 throw new InvalidKeySpecException("Invalid KeySpec"); 350 } 351 } 352 353 /** 354 * PBEWithMD2AndDES 355 */ 356 static public class PBEWithMD2KeyFactory 357 extends DESPBEKeyFactory 358 { 359 public PBEWithMD2KeyFactory() 360 { 361 super("PBEwithMD2andDES", PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, true, PKCS5S1, MD2, 64, 64); 362 } 363 } 364 365 /** 366 * PBEWithMD5AndDES 367 */ 368 static public class PBEWithMD5KeyFactory 369 extends DESPBEKeyFactory 370 { 371 public PBEWithMD5KeyFactory() 372 { 373 super("PBEwithMD5andDES", PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, true, PKCS5S1, MD5, 64, 64); 374 } 375 } 376 377 /** 378 * PBEWithSHA1AndDES 379 */ 380 static public class PBEWithSHA1KeyFactory 381 extends DESPBEKeyFactory 382 { 383 public PBEWithSHA1KeyFactory() 384 { 385 super("PBEwithSHA1andDES", PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, true, PKCS5S1, SHA1, 64, 64); 386 } 387 } 388 389 /** 390 * PBEWithMD2AndDES 391 */ 392 static public class PBEWithMD2 393 extends BaseBlockCipher 394 { 395 public PBEWithMD2() 396 { 397 super(new CBCBlockCipher(new DESEngine())); 398 } 399 } 400 401 /** 402 * PBEWithMD5AndDES 403 */ 404 static public class PBEWithMD5 405 extends BaseBlockCipher 406 { 407 public PBEWithMD5() 408 { 409 super(new CBCBlockCipher(new DESEngine())); 410 } 411 } 412 413 /** 414 * PBEWithSHA1AndDES 415 */ 416 static public class PBEWithSHA1 417 extends BaseBlockCipher 418 { 419 public PBEWithSHA1() 420 { 421 super(new CBCBlockCipher(new DESEngine())); 422 } 423 } 424 425 public static class Mappings 426 extends AlgorithmProvider 427 { 428 private static final String PREFIX = DES.class.getName(); 429 private static final String PACKAGE = "org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2 430 431 public Mappings() 432 { 433 } 434 435 public void configure(ConfigurableProvider provider) 436 { 437 438 provider.addAlgorithm("Cipher.DES", PREFIX + "$ECB"); 439 provider.addAlgorithm("Cipher." + OIWObjectIdentifiers.desCBC, PREFIX + "$CBC"); 440 441 addAlias(provider, OIWObjectIdentifiers.desCBC, "DES"); 442 443 provider.addAlgorithm("Cipher.DESRFC3211WRAP", PREFIX + "$RFC3211"); 444 445 provider.addAlgorithm("KeyGenerator.DES", PREFIX + "$KeyGenerator"); 446 447 provider.addAlgorithm("SecretKeyFactory.DES", PREFIX + "$KeyFactory"); 448 449 provider.addAlgorithm("Mac.DESCMAC", PREFIX + "$CMAC"); 450 provider.addAlgorithm("Mac.DESMAC", PREFIX + "$CBCMAC"); 451 provider.addAlgorithm("Alg.Alias.Mac.DES", "DESMAC"); 452 453 provider.addAlgorithm("Mac.DESMAC/CFB8", PREFIX + "$DESCFB8"); 454 provider.addAlgorithm("Alg.Alias.Mac.DES/CFB8", "DESMAC/CFB8"); 455 456 provider.addAlgorithm("Mac.DESMAC64", PREFIX + "$DES64"); 457 provider.addAlgorithm("Alg.Alias.Mac.DES64", "DESMAC64"); 458 459 provider.addAlgorithm("Mac.DESMAC64WITHISO7816-4PADDING", PREFIX + "$DES64with7816d4"); 460 provider.addAlgorithm("Alg.Alias.Mac.DES64WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING"); 461 provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1MACWITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING"); 462 provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING"); 463 464 provider.addAlgorithm("Mac.DESWITHISO9797", PREFIX + "$DES9797Alg3"); 465 provider.addAlgorithm("Alg.Alias.Mac.DESISO9797MAC", "DESWITHISO9797"); 466 467 provider.addAlgorithm("Mac.ISO9797ALG3MAC", PREFIX + "$DES9797Alg3"); 468 provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3", "ISO9797ALG3MAC"); 469 provider.addAlgorithm("Mac.ISO9797ALG3WITHISO7816-4PADDING", PREFIX + "$DES9797Alg3with7816d4"); 470 provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3MACWITHISO7816-4PADDING", "ISO9797ALG3WITHISO7816-4PADDING"); 471 472 provider.addAlgorithm("AlgorithmParameters.DES", PACKAGE + ".util.IvAlgorithmParameters"); 473 provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + OIWObjectIdentifiers.desCBC, "DES"); 474 475 provider.addAlgorithm("AlgorithmParameterGenerator.DES", PREFIX + "$AlgParamGen"); 476 provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + OIWObjectIdentifiers.desCBC, "DES"); 477 478 provider.addAlgorithm("Cipher.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2"); 479 provider.addAlgorithm("Cipher.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5"); 480 provider.addAlgorithm("Cipher.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1"); 481 482 provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES"); 483 provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES"); 484 provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES"); 485 486 provider.addAlgorithm("SecretKeyFactory.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2KeyFactory"); 487 provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5KeyFactory"); 488 provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1KeyFactory"); 489 490 provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES"); 491 provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDDES-CBC", "PBEWITHMD5ANDDES"); 492 provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDDES-CBC", "PBEWITHSHA1ANDDES"); 493 provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES"); 494 provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES"); 495 provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES"); 496 } 497 498 private void addAlias(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name) 499 { 500 provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid.getId(), name); 501 provider.addAlgorithm("Alg.Alias.KeyFactory." + oid.getId(), name); 502 } 503 } 504} 505