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