// using the prime and generator provided by valuelink; create a parameter object protected DHParameterSpec getDHParameterSpec() { String primeHex = (String) props.get("payment.valuelink.prime"); String genString = (String) props.get("payment.valuelink.generator"); // convert the p/g hex values byte[] primeByte = StringUtil.fromHexString(primeHex); BigInteger prime = new BigInteger(1, primeByte); // force positive (unsigned) BigInteger generator = new BigInteger(genString); // initialize the parameter spec DHParameterSpec dhParamSpec = new DHParameterSpec(prime, generator, 1024); return dhParamSpec; }
/** * Get a public key object for the ValueLink supplied public key * * @return PublicKey object of ValueLinks's public key * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public PublicKey getValueLinkPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException { // read the valuelink public key String publicValue = (String) props.get("payment.valuelink.publicValue"); byte[] publicKeyBytes = StringUtil.fromHexString(publicValue); // initialize the parameter spec DHParameterSpec dhParamSpec = this.getDHParameterSpec(); // load the valuelink public key KeyFactory keyFactory = KeyFactory.getInstance("DH"); BigInteger publicKeyInt = new BigInteger(publicKeyBytes); DHPublicKeySpec dhPublicSpec = new DHPublicKeySpec(publicKeyInt, dhParamSpec.getP(), dhParamSpec.getG()); PublicKey vlPublic = keyFactory.generatePublic(dhPublicSpec); return vlPublic; }
/** * Decrypt an encrypted pin using the configured keys * * @param pin Hex String of the encrypted pin (EAN) * @return Plain text String of the pin */ public String decryptPin(String pin) { // get the Cipher Cipher mwkCipher = this.getCipher(this.getMwkKey(), Cipher.DECRYPT_MODE); // decrypt pin String decryptedPinString = null; try { byte[] decryptedEan = mwkCipher.doFinal(StringUtil.fromHexString(pin)); byte[] decryptedPin = getByteRange(decryptedEan, 8, 8); decryptedPinString = new String(decryptedPin); } catch (IllegalStateException e) { Debug.logError(e, module); } catch (IllegalBlockSizeException e) { Debug.logError(e, module); } catch (BadPaddingException e) { Debug.logError(e, module); } if (debug) { Debug.logInfo("decryptPin : " + pin + " / " + decryptedPinString, module); } return decryptedPinString; }
protected byte[] getPrivateKeyBytes() { return StringUtil.fromHexString(this.getGenericValue().getString("privateKey")); }
protected byte[] getKek() { return StringUtil.fromHexString(this.getGenericValue().getString("exchangeKey")); }
protected byte[] getMwk() { return StringUtil.fromHexString(this.getGenericValue().getString("workingKey")); }
private StringBuffer outputKeyCreation(int loop, boolean kekOnly, String kekTest) { StringBuffer buf = new StringBuffer(); loop++; if (loop > 100) { // only loop 100 times; then throw an exception throw new IllegalStateException("Unable to create 128 byte keys in 100 tries"); } // place holder for the keys DHPrivateKey privateKey = null; DHPublicKey publicKey = null; if (!kekOnly) { KeyPair keyPair = null; try { keyPair = this.createKeys(); } catch (NoSuchAlgorithmException e) { Debug.logError(e, module); } catch (InvalidAlgorithmParameterException e) { Debug.logError(e, module); } catch (InvalidKeySpecException e) { Debug.logError(e, module); } if (keyPair != null) { publicKey = (DHPublicKey) keyPair.getPublic(); privateKey = (DHPrivateKey) keyPair.getPrivate(); if (publicKey == null || publicKey.getY().toByteArray().length != 128) { // run again until we get a 128 byte public key for VL return this.outputKeyCreation(loop, kekOnly, kekTest); } } else { Debug.logInfo("Returned a null KeyPair", module); return this.outputKeyCreation(loop, kekOnly, kekTest); } } else { // use our existing private key to generate a KEK try { privateKey = (DHPrivateKey) this.getPrivateKey(); } catch (Exception e) { Debug.logError(e, module); } } // the KEK byte[] kekBytes = null; try { kekBytes = this.generateKek(privateKey); } catch (NoSuchAlgorithmException e) { Debug.logError(e, module); } catch (InvalidKeySpecException e) { Debug.logError(e, module); } catch (InvalidKeyException e) { Debug.logError(e, module); } // the 3DES KEK value SecretKey loadedKek = this.getDesEdeKey(kekBytes); byte[] loadKekBytes = loadedKek.getEncoded(); // test the KEK Cipher cipher = this.getCipher(this.getKekKey(), Cipher.ENCRYPT_MODE); byte[] kekTestB = {0, 0, 0, 0, 0, 0, 0, 0}; byte[] kekTestC = new byte[0]; if (kekTest != null) { kekTestB = StringUtil.fromHexString(kekTest); } // encrypt the test bytes try { kekTestC = cipher.doFinal(kekTestB); } catch (Exception e) { Debug.logError(e, module); } if (!kekOnly) { // public key (just Y) BigInteger y = publicKey.getY(); byte[] yBytes = y.toByteArray(); String yHex = StringUtil.toHexString(yBytes); buf.append("======== Begin Public Key (Y @ ") .append(yBytes.length) .append(" / ") .append(yHex.length()) .append(") ========\n"); buf.append(yHex).append("\n"); buf.append("======== End Public Key ========\n\n"); // private key (just X) BigInteger x = privateKey.getX(); byte[] xBytes = x.toByteArray(); String xHex = StringUtil.toHexString(xBytes); buf.append("======== Begin Private Key (X @ ") .append(xBytes.length) .append(" / ") .append(xHex.length()) .append(") ========\n"); buf.append(xHex).append("\n"); buf.append("======== End Private Key ========\n\n"); // private key (full) byte[] privateBytes = privateKey.getEncoded(); String privateHex = StringUtil.toHexString(privateBytes); buf.append("======== Begin Private Key (Full @ ") .append(privateBytes.length) .append(" / ") .append(privateHex.length()) .append(") ========\n"); buf.append(privateHex).append("\n"); buf.append("======== End Private Key ========\n\n"); } if (kekBytes != null) { buf.append("======== Begin KEK (").append(kekBytes.length).append(") ========\n"); buf.append(StringUtil.toHexString(kekBytes)).append("\n"); buf.append("======== End KEK ========\n\n"); buf.append("======== Begin KEK (DES) (").append(loadKekBytes.length).append(") ========\n"); buf.append(StringUtil.toHexString(loadKekBytes)).append("\n"); buf.append("======== End KEK (DES) ========\n\n"); buf.append("======== Begin KEK Test (").append(kekTestC.length).append(") ========\n"); buf.append(StringUtil.toHexString(kekTestC)).append("\n"); buf.append("======== End KEK Test ========\n\n"); } else { Debug.logError("KEK came back empty", module); } return buf; }