⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 valuelinkapi.java

📁 国外的一套开源CRM
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            // private key (just X)
            BigInteger x = privateKey.getX();
            byte[] xBytes = x.toByteArray();
            String xHex = StringUtil.toHexString(xBytes);
            buf.append("======== Begin Private Key (X @ " + xBytes.length + " / " + xHex.length() + ") ========\n");
            buf.append(xHex + "\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 @ " + privateBytes.length + " / " + privateHex.length() + ") ========\n");
            buf.append(privateHex + "\n");
            buf.append("======== End Private Key ========\n\n");
        }

        if (kekBytes != null) {
            buf.append("======== Begin KEK (" + kekBytes.length + ") ========\n");
            buf.append(StringUtil.toHexString(kekBytes) + "\n");
            buf.append("======== End KEK ========\n\n");

            buf.append("======== Begin KEK (DES) (" + loadKekBytes.length + ") ========\n");
            buf.append(StringUtil.toHexString(loadKekBytes) + "\n");
            buf.append("======== End KEK (DES) ========\n\n");

            buf.append("======== Begin KEK Test (" + kekTestC.length + ") ========\n");
            buf.append(StringUtil.toHexString(kekTestC) + "\n");
            buf.append("======== End KEK Test ========\n\n");
        } else {
            Debug.logError("KEK came back empty", module);
        }

        return buf;
    }

    /**
     * Create a set of public/private keys using ValueLinks defined parameters
     * @return KeyPair object containing both public and private keys
     * @throws NoSuchAlgorithmException
     * @throws InvalidAlgorithmParameterException
     */
    public KeyPair createKeys() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeySpecException {
        // initialize the parameter spec
        DHPublicKey publicKey = (DHPublicKey) this.getValueLinkPublicKey();
        DHParameterSpec dhParamSpec = publicKey.getParams();
        //Debug.log(dhParamSpec.getP().toString() + " / " + dhParamSpec.getG().toString(), module);

        // create the public/private key pair using parameters defined by valuelink
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
        keyGen.initialize(dhParamSpec);
        KeyPair keyPair = keyGen.generateKeyPair();

        return keyPair;
    }

    /**
     * Generate a key exchange key for use in encrypting the mwk
     * @param privateKey The private key for the merchant
     * @return byte array containing the kek
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws InvalidKeyException
     */
    public byte[] generateKek(PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
        // get the ValueLink public key
        PublicKey vlPublic = this.getValueLinkPublicKey();

        // generate shared secret key
        KeyAgreement ka = KeyAgreement.getInstance("DH");
        ka.init(privateKey);
        ka.doPhase(vlPublic, true);
        byte[] secretKey = ka.generateSecret();

        if (debug) {
            Debug.log("Secret Key : " + StringUtil.toHexString(secretKey) + " / " + secretKey.length,  module);
        }

        // generate 3DES from secret key using VL algorithm (KEK)
        MessageDigest md = MessageDigest.getInstance("SHA1");
        byte[] digest = md.digest(secretKey);
        byte[] des2 = getByteRange(digest, 0, 16);
        byte[] first8 = getByteRange(des2, 0, 8);
        byte[] kek = copyBytes(des2, first8, 0);

        if (debug) {
            Debug.log("Generated KEK : " + StringUtil.toHexString(kek) + " / " + kek.length, module);
        }

        return kek;
    }

    /**
     * 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;
    }

    /**
     * Get merchant Private Key
     * @return PrivateKey object for the merchant
     */
    public PrivateKey getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException {
        byte[] privateKeyBytes = this.getPrivateKeyBytes();

        // initialize the parameter spec
        DHParameterSpec dhParamSpec = this.getDHParameterSpec();

        // load the private key
        KeyFactory keyFactory = KeyFactory.getInstance("DH");
        BigInteger privateKeyInt = new BigInteger(privateKeyBytes);
        DHPrivateKeySpec dhPrivateSpec = new DHPrivateKeySpec(privateKeyInt, dhParamSpec.getP(), dhParamSpec.getG());
        PrivateKey privateKey = keyFactory.generatePrivate(dhPrivateSpec);

        return privateKey;
    }

    /**
     * Generate a new MWK
     * @return Hex String of the new encrypted MWK ready for transmission to ValueLink
     */
    public byte[] generateMwk() {
        KeyGenerator keyGen = null;
        try {
            keyGen = KeyGenerator.getInstance("DES");
        } catch (NoSuchAlgorithmException e) {
            Debug.logError(e, module);
        }

        // generate the DES key 1
        SecretKey des1 = keyGen.generateKey();
        SecretKey des2 = keyGen.generateKey();

        if (des1 != null && des2 != null) {
            byte[] desByte1 = des1.getEncoded();
            byte[] desByte2 = des2.getEncoded();
            byte[] desByte3 = des1.getEncoded();

            // check for weak keys
            try {
                if (DESKeySpec.isWeak(des1.getEncoded(), 0) || DESKeySpec.isWeak(des2.getEncoded(), 0)) {
                    return generateMwk();
                }
            } catch (Exception e) {
                Debug.logError(e, module);
            }

            byte[] des3 = copyBytes(desByte1, copyBytes(desByte2, desByte3, 0), 0);            
            return generateMwk(des3);
        } else {
            Debug.log("Null DES keys returned", module);
        }

        return null;
    }

    /**
     * Generate a new MWK
     * @param desBytes byte array of the DES key (24 bytes)
     * @return Hex String of the new encrypted MWK ready for transmission to ValueLink
     */
    public byte[] generateMwk(byte[] desBytes) {
        if (debug) {
            Debug.log("DES Key : " + StringUtil.toHexString(desBytes) + " / " + desBytes.length, module);
        }
        SecretKeyFactory skf1 = null;
        SecretKey mwk = null;
        try {
            skf1 = SecretKeyFactory.getInstance("DESede");
        } catch (NoSuchAlgorithmException e) {
            Debug.logError(e, module);
        }
        DESedeKeySpec desedeSpec2 = null;
        try {
            desedeSpec2 = new DESedeKeySpec(desBytes);
        } catch (InvalidKeyException e) {
            Debug.logError(e, module);
        }
        if (skf1 != null && desedeSpec2 != null) {
            try {
                mwk = skf1.generateSecret(desedeSpec2);
            } catch (InvalidKeySpecException e) {
                Debug.logError(e, module);
            }
        }
        if (mwk != null) {
            return generateMwk(mwk);
        } else {
            return null;
        }
    }

    /**
     * Generate a new MWK
     * @param mwkdes3 pre-generated DES3 SecretKey
     * @return Hex String of the new encrypted MWK ready for transmission to ValueLink
     */
    public byte[] generateMwk(SecretKey mwkdes3) {
        // zeros for checksum
        byte[] zeros = { 0, 0, 0, 0, 0, 0, 0, 0 };

        // 8 bytes random data
        byte[] random = new byte[8];
        Random ran = new Random();
        ran.nextBytes(random);


        // open a cipher using the new mwk
        Cipher cipher = this.getCipher(mwkdes3, Cipher.ENCRYPT_MODE);

        // make the checksum - encrypted 8 bytes of 0's
        byte[] encryptedZeros = new byte[0];
        try {
            encryptedZeros = cipher.doFinal(zeros);
        } catch (IllegalStateException e) {
            Debug.logError(e, module);
        } catch (IllegalBlockSizeException e) {
            Debug.logError(e, module);
        } catch (BadPaddingException e) {
            Debug.logError(e, module);
        }

        // make the 40 byte MWK - random 8 bytes + key + checksum
        byte[] newMwk = copyBytes(mwkdes3.getEncoded(), encryptedZeros, 0);
        newMwk = copyBytes(random, newMwk, 0);

        if (debug) {
            Debug.log("Random 8 byte : " + StringUtil.toHexString(random), module);
            Debug.log("Encrypted 0's : " + StringUtil.toHexString(encryptedZeros), module);
            Debug.log("Decrypted MWK : " + StringUtil.toHexString(mwkdes3.getEncoded()) + " / " + mwkdes3.getEncoded().length, module);
            Debug.log("Encrypted MWK : " + StringUtil.toHexString(newMwk) + " / " + newMwk.length, module);
        }

        return newMwk;
    }

    /**
     * Use the KEK to encrypt a value usually the MWK
     * @param content byte array to encrypt
     * @return encrypted byte array
     */
    public byte[] encryptViaKek(byte[] content) {
        return cryptoViaKek(content, Cipher.ENCRYPT_MODE);
    }

    /**
     * Ue the KEK to decrypt a value
     * @param content byte array to decrypt
     * @return decrypted byte array
     */
    public byte[] decryptViaKek(byte[] content) {
        return cryptoViaKek(content, Cipher.DECRYPT_MODE);
    }

    /**
     * Returns a date string formatted as directed by ValueLink
     * @return ValueLink formatted date String
     */
    public String getDateString() {
        String format = (String) props.get("payment.valuelink.timestamp");
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date());
    }

    /**
     * Returns the current working key index
     * @return Long number of the current working key index
     */
    public Long getWorkingKeyIndex() {
        if (this.mwkIndex == null) {
            synchronized(this) {
                if (this.mwkIndex == null) {
                    this.mwkIndex = this.getGenericValue().getLong("workingKeyIndex");
                }
            }
        }

        if (debug) {
            Debug.log("Current Working Key Index : " + this.mwkIndex, module);
        }

        return this.mwkIndex;
    }

    /**
     * Returns a ValueLink formatted amount String
     * @param amount Double value to format
     * @return Formatted String
     */
    public String getAmount(Double amount) {
        if (amount == null) {
            return "0.00";
        }
        String currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00");
        DecimalFormat formatter = new DecimalFormat(currencyFormat);
        String amountString = formatter.format(amount.doubleValue());
        Double newAmount = null;
        try {
            newAmount = new Double(formatter.parse(amountString).doubleValue());
        } catch (ParseException e) {
            Debug.logError(e, "Unable to parse amount Double");
        }

        String formattedString = null;
        if (newAmount != null) {
            double amountDouble = newAmount.doubleValue() * 100;
            formattedString = new String(new Integer(new Double(amountDouble).intValue()).toString());
        }
        return formattedString;
    }

    /**
     * Returns a Double from a ValueLink formatted amount String
     * @param amount The ValueLink formatted amount String
     * @return Double object
     */
    public Double getAmount(String amount) {
        if (amount == null) {
            return new Double(0.00);
        }
        Double doubleAmount = new Double(amount);
        return new Double(doubleAmount.doubleValue() / 100);
    }
    
    public String getCurrency(String currency) {
        return "840"; // todo make this multi-currency
    }

    /**
     * Creates a Map of initial request values (MerchID, AltMerchNo, Modes, MerchTime, TermTxnNo, EncryptID)
     * Note: For 2010 (assign working key) transaction, the EncryptID will need to be adjusted
     * @return Map containing the inital request values
     */
    public Map getInitialRequestMap(Map context) {
        Map request = new HashMap();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -