1 21 22 package org.apache.derby.impl.drda; 23 24 import java.security.KeyPairGenerator ; 25 import java.security.KeyPair ; 26 import javax.crypto.KeyAgreement; 27 import javax.crypto.spec.DHParameterSpec; 28 import javax.crypto.interfaces.DHPublicKey; 29 import javax.crypto.spec.DHPublicKeySpec; 30 import javax.crypto.spec.SecretKeySpec; 31 import javax.crypto.Cipher; 32 import javax.crypto.spec.IvParameterSpec; 33 import java.security.spec.AlgorithmParameterSpec ; 34 import java.security.KeyFactory ; 35 import java.security.PublicKey ; 36 import java.sql.SQLException ; 37 import java.math.BigInteger ; 38 import org.apache.derby.shared.common.sanity.SanityManager; 39 40 48 49 class DecryptionManager 50 { 51 private static final byte modulusBytes__[] = { 53 (byte)0xC6, (byte)0x21, (byte)0x12, (byte)0xD7, 54 (byte)0x3E, (byte)0xE6, (byte)0x13, (byte)0xF0, 55 (byte)0x94, (byte)0x7A, (byte)0xB3, (byte)0x1F, 56 (byte)0x0F, (byte)0x68, (byte)0x46, (byte)0xA1, 57 (byte)0xBF, (byte)0xF5, (byte)0xB3, (byte)0xA4, 58 (byte)0xCA, (byte)0x0D, (byte)0x60, (byte)0xBC, 59 (byte)0x1E, (byte)0x4C, (byte)0x7A, (byte)0x0D, 60 (byte)0x8C, (byte)0x16, (byte)0xB3, (byte)0xE3 61 }; 62 63 private static final BigInteger modulus__ 66 = new BigInteger (1, modulusBytes__); 67 68 private static final byte baseBytes__[] = { 70 (byte)0x46, (byte)0x90, (byte)0xFA, (byte)0x1F, 71 (byte)0x7B, (byte)0x9E, (byte)0x1D, (byte)0x44, 72 (byte)0x42, (byte)0xC8, (byte)0x6C, (byte)0x91, 73 (byte)0x14, (byte)0x60, (byte)0x3F, (byte)0xDE, 74 (byte)0xCF, (byte)0x07, (byte)0x1E, (byte)0xDC, 75 (byte)0xEC, (byte)0x5F, (byte)0x62, (byte)0x6E, 76 (byte)0x21, (byte)0xE2, (byte)0x56, (byte)0xAE, 77 (byte)0xD9, (byte)0xEA, (byte)0x34, (byte)0xE4 78 }; 79 80 private static final BigInteger base__ = 83 new BigInteger (1, baseBytes__); 84 85 private static final int exponential_length__ = 255; 87 88 private KeyPairGenerator keyPairGenerator_; 89 private KeyPair keyPair_; 90 private KeyAgreement keyAgreement_; 91 private DHParameterSpec paramSpec_; 92 93 private final static String SHA_1_PRNG_ALGORITHM = "SHA1PRNG"; 95 private final static int SECMEC_USRSSBPWD_SEED_LEN = 8; 97 103 DecryptionManager () throws SQLException 104 { 105 try { 106 if (java.security.Security.getProvider ("IBMJCE") == null) java.security.Security.addProvider ((java.security.Provider ) Class.forName("IBMJCE").newInstance()); 108 paramSpec_ = new DHParameterSpec (modulus__, base__, exponential_length__); 109 keyPairGenerator_ = KeyPairGenerator.getInstance ("DH", "IBMJCE"); 110 keyPairGenerator_.initialize ((AlgorithmParameterSpec )paramSpec_); 111 keyPair_ = keyPairGenerator_.generateKeyPair(); 112 keyAgreement_ = KeyAgreement.getInstance ("DH", "IBMJCE"); 113 keyAgreement_.init (keyPair_.getPrivate()); 114 } 115 catch (java.lang.ClassNotFoundException e) { 116 throw new SQLException ("java.lang.ClassNotFoundException is caught" + 117 " when initializing EncryptionManager '" + e.getMessage() + "'"); 118 } 119 catch (java.lang.IllegalAccessException e) { 120 throw new SQLException ("java.lang.IllegalAccessException is caught" + 121 " when initializing EncryptionManager '" + e.getMessage() + "'"); 122 } 123 catch (java.lang.InstantiationException e) { 124 throw new SQLException ("java.lang.InstantiationException is caught" + 125 " when initializing EncryptionManager '" + e.getMessage() + "'"); 126 } 127 catch (java.security.NoSuchProviderException e) { 128 throw new SQLException ("java.security.NoSuchProviderException is caught" + 129 " when initializing EncryptionManager '" + e.getMessage() + "'"); 130 } 131 catch (java.security.NoSuchAlgorithmException e) { 132 throw new SQLException ("java.security.NoSuchAlgorithmException is caught" + 133 " when initializing EncryptionManager '" + e.getMessage() + "'"); 134 } 135 catch (java.security.InvalidAlgorithmParameterException e) { 136 throw new SQLException ("java.security.InvalidAlgorithmParameterException is caught" + 137 " when initializing EncryptionManager '" + e.getMessage() + "'"); 138 } 139 140 catch (java.security.InvalidKeyException e) { 141 throw new SQLException ("java.security.InvalidKeyException is caught" + 142 " when initializing EncryptionManager '" + e.getMessage() + "'"); 143 } 144 } 145 146 155 public byte[] obtainPublicKey () 156 { 157 byte[] publicEnc = keyPair_.getPublic().getEncoded(); 159 160 BigInteger aPub = ((DHPublicKey) keyPair_.getPublic()).getY(); 163 byte[] aPubKey = aPub.toByteArray(); 164 165 if (aPubKey.length == 33 && aPubKey[0]==0) { 173 byte[] newKey = new byte[32]; 174 for (int i=0; i < newKey.length; i++) 175 newKey[i] = aPubKey[i+1]; 176 return newKey; 177 } 178 179 if (aPubKey.length < 32) { 184 byte[] newKey = new byte[32]; 185 int i; 186 for (i=0; i < 32-aPubKey.length; i++) { 187 newKey[i] = 0; 188 } 189 for (int j=i; j<newKey.length; j++) 190 newKey[j] = aPubKey[j-i]; 191 return newKey; 192 } 193 return aPubKey; 194 } 195 196 209 private byte[] calculateDecryptionToken (int securityMechanism, byte[] initVector) 210 { 211 byte[] token = new byte[8]; 212 213 if (securityMechanism == 7) { 215 if (initVector.length < 8) { for (int i=0; i<initVector.length; i++) 217 token[i] = initVector[i]; 218 for (int i=initVector.length; i<8; i++) 219 token[i] = 0; 220 } 221 else { for (int i=0; i<8; i++) 223 token[i] = initVector[i]; 224 } 225 } 226 else if (securityMechanism == 9) { 229 for (int i = 0; i < 8; i++) { 230 token[i] = initVector[i + 12]; 231 } 232 } 233 return token; 234 } 235 236 249 public byte[] decryptData (byte[] cipherText, 250 int securityMechanism, 251 byte[] initVector, 252 byte[] sourcePublicKey) throws SQLException 253 { 254 byte[] plainText = null; 255 byte[] token = calculateDecryptionToken (securityMechanism, initVector); 256 try { 257 258 KeyFactory keyFac = KeyFactory.getInstance ("DH", "IBMJCE"); 260 261 BigInteger publicKey = new BigInteger (1, sourcePublicKey); 264 DHPublicKeySpec dhKeySpec = new DHPublicKeySpec (publicKey, modulus__, base__); 265 PublicKey pubKey = keyFac.generatePublic (dhKeySpec); 266 267 keyAgreement_.doPhase (pubKey, true); 269 270 byte[] sharedSecret = keyAgreement_.generateSecret(); 274 byte[] newKey = new byte[32]; 275 276 if (sharedSecret.length == 33 && sharedSecret[0] == 0) { 280 for (int i=0; i<newKey.length; i++) 281 newKey[i] = sharedSecret[i+1]; 282 } 283 if (sharedSecret.length < 32) { 284 int i; 285 for (i=0; i<(32 - sharedSecret.length); i++) 286 newKey[i] = 0; 287 for (int j=i; j<sharedSecret.length; j++) 288 newKey[j] = sharedSecret[j-i]; 289 } 290 291 byte[] key = new byte[8]; 299 300 if (sharedSecret.length==32) { 302 for (int i=0; i< 8;i++) 303 key[i] = sharedSecret[i+12]; 304 } 305 else if (sharedSecret.length==33 || sharedSecret.length < 32) { 306 for (int i=0; i< 8;i++) 307 key[i] = newKey[i+12]; 308 } 309 else 310 throw new SQLException ("sharedSecret key length error " + sharedSecret.length); 311 312 byte temp; 314 int changeParity; 315 for (int i=0; i<8; i++) 316 { 317 temp = key[i]; 318 changeParity = 1; 319 for (int j=0; j<8; j++) 320 { 321 if (temp < 0) 322 changeParity = 1 - changeParity; 323 temp = (byte) (temp << 1); 324 } 325 if (changeParity == 1) 326 { 327 if ((key[i] & 1) != 0) 328 key[i] &= 0xfe; 329 else 330 key[i] |= 1; 331 } 332 } 333 334 SecretKeySpec desKey = new SecretKeySpec (key, "DES"); 336 337 Cipher cipher= Cipher.getInstance ("DES/CBC/PKCS5Padding", "IBMJCE"); 343 344 IvParameterSpec ivParam = new IvParameterSpec (token); 347 348 cipher.init (javax.crypto.Cipher.DECRYPT_MODE, desKey,ivParam); 351 352 plainText = cipher.doFinal (cipherText); 354 } 355 catch (java.security.NoSuchProviderException e) { 356 throw new SQLException ("java.security.NoSuchProviderException is caught " 357 + "when encrypting data '" + e.getMessage() + "'"); 358 } 359 catch (java.security.NoSuchAlgorithmException e) { 360 throw new SQLException ("java.security.NoSuchAlgorithmException is caught " 361 + "when encrypting data '" + e.getMessage() + "'"); 362 } 363 catch (java.security.spec.InvalidKeySpecException e) { 364 throw new SQLException ("java.security.InvalidKeySpecException is caught " 365 + "when encrypting data"); 366 } 367 catch (java.security.InvalidKeyException e) { 368 throw new SQLException ("java.security.InvalidKeyException is caught " 369 + "when encrypting data '" + e.getMessage() + "'"); 370 } 371 catch (javax.crypto.NoSuchPaddingException e) { 372 throw new SQLException ("javax.crypto.NoSuchPaddingException is caught " 373 + "when encrypting data '" + e.getMessage() + "'"); 374 } 375 catch (javax.crypto.BadPaddingException e) { 376 throw new SQLException ("javax.crypto.BadPaddingException is caught " 377 + "when encrypting data '" + e.getMessage() + "'"); 378 } 379 catch (java.security.InvalidAlgorithmParameterException e) { 380 throw new SQLException ("java.security.InvalidAlgorithmParameterException is caught " 381 + "when encrypting data '" + e.getMessage() + "'"); 382 } 383 catch (javax.crypto.IllegalBlockSizeException e) { 384 throw new SQLException ("javax.crypto.IllegalBlockSizeException is caught " 385 + "when encrypting data '" + e.getMessage() + "'"); 386 } 387 return plainText; 388 } 389 390 397 protected static byte[] generateSeed() throws SQLException { 398 java.security.SecureRandom secureRandom = null; 399 try { 400 secureRandom = 403 java.security.SecureRandom.getInstance(SHA_1_PRNG_ALGORITHM); 404 } catch (java.security.NoSuchAlgorithmException nsae) { 405 throw new SQLException ( 406 "java.security.NoSuchAlgorithmException is caught" + 407 " when initializing DecryptionManager '" + 408 nsae.getMessage() + "'"); 409 } 410 byte randomSeedBytes[] = new byte[SECMEC_USRSSBPWD_SEED_LEN]; 411 secureRandom.setSeed(secureRandom.generateSeed( 412 SECMEC_USRSSBPWD_SEED_LEN)); 413 secureRandom.nextBytes(randomSeedBytes); 414 return randomSeedBytes; 416 } 417 418 423 424 private static char[] hex_table = { 425 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 426 'a', 'b', 'c', 'd', 'e', 'f' 427 }; 428 429 445 protected static String toHexString(byte[] data, int offset, int length) 446 { 447 StringBuffer s = new StringBuffer (length*2); 448 int end = offset+length; 449 450 for (int i = offset; i < end; i++) 451 { 452 int high_nibble = (data[i] & 0xf0) >>> 4; 453 int low_nibble = (data[i] & 0x0f); 454 s.append(hex_table[high_nibble]); 455 s.append(hex_table[low_nibble]); 456 } 457 458 return s.toString(); 459 } 460 461 479 protected static byte[] toHexByte(String str, int offset, int length) 480 { 481 byte[] data = new byte[(length - offset) * 2]; 482 int end = offset+length; 483 484 for (int i = offset; i < end; i++) 485 { 486 char ch = str.charAt(i); 487 int high_nibble = (ch & 0xf0) >>> 4; 488 int low_nibble = (ch & 0x0f); 489 data[i] = (byte)high_nibble; 490 data[i+1] = (byte)low_nibble; 491 } 492 return data; 493 } 494 } 495 | Popular Tags |