zoukankan      html  css  js  c++  java
  • php RSA 加密 与java加密互交,java解密

    <?

    php class encrypt{ var $pub_key; function redPukey() { $pubKey = "MIIDhzCCAm+gAwIBAgIGASYISh96MA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNVBAYTAkNOMSkwJwYDVQQKDCBBbGxpbnBheSBOZXR3b3JrIFNlcnZpY2VzIENvLkx0ZDElMCMGA1UECwwcQWxsaW5wYXkgUHJpbWFyeSBDZXJ0aWZpY2F0ZTAeFw0xMDAxMDcxMDE3NDBaFw0zMDAxMDIxMDE3NDBaMGQxCzAJBgNVBAYTAkNOMSkwJwYDVQQKDCBBbGxpbnBheSBOZXR3b3JrIFNlcnZpY2VzIENvLkx0ZDEqMCgGA1UECwwhQWxsaW5wYXkgRGlnaXRhbCBTaWduIENlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEv2q2/xN5PF0dLn1vhIaVlyWsvJFVFxWgH7sQBObzYbZXOOVzoQpmXuSFOrF0/ol4Okd/2OGfdXUUFSUZfzAQOT1Wmjupec7z2V6l4/PT7aOg6t/MJwU9aW9Iw+AFzM1vnLOXdTlWVLZbtB7IiJ/HhfwBDkyvhp1zNYoAPrwC5QIDAQABo4HHMIHEMB0GA1UdDgQWBBQlWQA//YbuEdfE1yP+PpnokDO8WDCBjgYDVR0jBIGGMIGDgBSBWR3Bvx8To7TrecKhCM4smeabN6FjpGEwXzELMAkGA1UEBhMCQ04xKTAnBgNVBAoMIEFsbGlucGF5IE5ldHdvcmsgU2VydmljZXMgQ28uTHRkMSUwIwYDVQQLDBxBbGxpbnBheSBQcmltYXJ5IENlcnRpZmljYXRlggYBJghKHowwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQUFAAOCAQEATzT9GuAmAXLSWpoGc0F7Km7DPMWvSAkq8ckJLftF0/lB3JTR6QT5rsTnQHCdRU7SJX+eLNwhJQdRg34dPJAI2z/HpgGu7tW7pdsHjCjlVae3I64h2OzYBGXdtdRyPmyXfBOgXUfqtH0Fg+1QqsRmcRugywjZH8ZQAVYm0TkVJmdBknPp60bJ2gE/nj0w6VaSL6HMAQ+A7AVne3NDreBXepMHgiFqiqMHrZFBQCgTSR1UwZoT8hwXaaUgwf2h9l/D2QOGCD8G3sRKfMsH3clkehXbprWPNk3uww7dCT0pGz845AyKzCmRK60Z/NOgMG5X+f+JmugsS/bKYwjetXHg9Q=="; $pem = chunk_split($pubKey,64," ");//转换为pem格式的公钥 $pem = "-----BEGIN CERTIFICATE----- ".$pem."-----END CERTIFICATE----- "; $publicKey = openssl_pkey_get_public($pem); //$certificateCAcerContent = file_get_contents("../cer/cert_usercenter/TLCert4Sign_test.cer"); //$pub_key = openssl_get_publickey($certificateCAcerContent); //return $pub_key; return $publicKey; } /* 签名数据: data:utf-8编码的订单原文, privatekeyFile:私钥路径 passphrase:私钥password 返回:base64转码的签名数据 */ function sign($data) { //证书路径 $privatekeyFile="../cer/testMemberKey.pfx"; //证书私钥 $passphrase="testMemberKey"; $signature = ''; $privateKey; $signedMsg; $pkcs12 = file_get_contents($privatekeyFile); if (openssl_pkcs12_read($pkcs12, $certs, "testMemberKey")) { $privateKey = $certs['pkey']; } if (openssl_sign($data, $signedMsg, $privateKey,OPENSSL_ALGO_SHA1)) { $signedMsg= strtoupper(bin2hex($signedMsg));//这个看情况。有些不须要转换成16进制,有些须要base64编码。

    看各个接口 return $signedMsg; } // $privatekey = openssl_pkey_get_private(file_get_contents($privatekeyFile),$passphrase); // $res=openssl_get_privatekey($privatekey); //openssl_sign($data, $signature, $res); // openssl_free_key($res); // return base64_encode($signature); return $privateKey; } function pubkeyEncrypt($data,$panText,$pubkey){ openssl_public_encrypt($data,$panText,$pubkey,OPENSSL_PKCS1_PADDING); return strtoupper(bin2hex($panText)); } function getBytes($string) { $bytes = array(); for($i = 0; $i < strlen($string); $i++){ $bytes[] = ord($string[$i]); } return $bytes; } } ?>


    <?

    php require_once("encrypt.php"); $dateEncrypt=new encrypt(); $pukey=$dateEncrypt->redPukey(); //公钥加密 $userName= $dateEncrypt->pubkeyEncrypt("測试数据",$userName,$pukey); echo $userName; //私钥加密 $signBytes=$dateEncrypt->sign($signSrc); echo $signBytes; ?>


    參考php 手冊—>函数拓展—>加密拓展


    php  RSA  加密  加密结果每次都会不一样,这是正确的。 跟java 有差别。java  结果不会变。可是java  能解出来。


    证书都须要转换下  pem 格式才干使用。





    java   部分

    package com.allinpay.common.util;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.Key;
    import java.security.KeyPair;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.SignatureException;
    import java.security.UnrecoverableKeyException;
    import java.security.cert.Certificate;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    public class CertSignUtil {
    
        /**
         * 測试方法 从keystore中获得公私钥对
         * 
         * @param filePath
         *            keystore文件路径
         * @param keyStorePassword
         *            keystore password
         * @param masterPassword
         *            私钥主password。能够和keystorepassword同样也可不同
         * @param alias
         *            密钥对别名
         */
        public static KeyPair getKeyFromKeyStore(String filePath,
                String keyStorePassword, String masterPassword, String alias) {
    
            KeyPair keyPair = null;
    
            try {
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(new FileInputStream(filePath),
                        keyStorePassword.toCharArray());
    
                Key key = keyStore.getKey(alias, masterPassword.toCharArray());
                // 也能够从keyStore中直接读公钥证书,无须通过私钥转换
                // Certificate cert = keyStore.getCertificate(alias);
                // PublicKey pubKey = cert.getPublicKey();
    
                if (key instanceof PrivateKey) {
                    Certificate cert = keyStore.getCertificate(alias);
                    keyPair = new KeyPair(cert.getPublicKey(), (PrivateKey) key);
                }
    
                PrivateKey privateKey = keyPair.getPrivate();
                PublicKey publicKey = keyPair.getPublic();
    
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (UnrecoverableKeyException e) {
                e.printStackTrace();
            }
    
            return keyPair;
        }
    
        /**
         * 使用私钥证书签名
         * 
         * @param priKey
         *            私钥对象
         * @param plainText
         *            明文文本的字节数组
         * @param encAlg
         *            加密算法
         * @param signAlg
         *            签名算法
         * @return 加密后的密文串
         * 
         * @see verifyByPubKey
         */
        public static byte[] signByPriKey(Key priKey, byte[] srcBytes,
                String signAlg) {
            // 签名
            byte[] signBytes = null;
            try {
                Signature sign = Signature.getInstance(signAlg,
                        new BouncyCastleProvider());
                sign.initSign((PrivateKey) priKey);
                sign.update(srcBytes);
                signBytes = sign.sign();
            } catch (NoSuchAlgorithmException e) {
                // LoggerUtil.error("私钥签名 - 无效算法:");
            } catch (InvalidKeyException e) {
                // LoggerUtil.error("私钥签名 - 无效的密钥:");
            } catch (SignatureException e) {
                // LoggerUtil.error("私钥签名 - 签名异常:");
            }
    
            return signBytes;
        }
    
        /**
         * Byte数组转十六进制字符串,字节间不用空格分隔
         * 
         * @param b
         * @return
         */
        public static String bytes2HexString(byte[] b) {
            String ret = "";
            for (int i = 0; i < b.length; i++) {
                String hex = Integer.toHexString(b[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                ret += hex.toUpperCase();
            }
            return ret;
        }
    
        /**
         * 将指定字符串src,以每两个字符切割转换为16进制形式 如:"2B44EFD9" --> byte[]{0x2B, 0x44, 0xEF,
         * 0xD9}
         * 
         * @param src
         *            String格式字符串
         * @return byte[]
         */
        public static byte[] hexString2Bytes(String src) {
            if (src.length() % 2 != 0) {
                src = src + "0";
            }
            byte[] ret = new byte[src.length() / 2];
            byte[] tmp = src.getBytes();
            for (int i = 0; i < (src.length() / 2); i++) {
                ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
            }
            return ret;
        }
    
        /**
         * 将两个ASCII字符合成一个字节。 如:"EF"--> 0xEF
         * 
         * @param src0
         *            byte
         * @param src1
         *            byte
         * @return byte
         */
        public static byte uniteBytes(byte src0, byte src1) {
            byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
                    .byteValue();
            _b0 = (byte) (_b0 << 4);// 左移4bit。变成8位里的高4位
            byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
                    .byteValue();// 不左移。保持在低4位
            byte ret = (byte) (_b0 ^ _b1);// 按位异或就可以
            return ret;
        }
    
        /**
         * 使用公钥验证签名
         * 
         * @param pubKey
         *            公钥
         * @param srcBytes
         *            签名原串字节数组
         * @param signBytes
         *            签名串字节数组
         * @param signAlg
         *            签名算法
         * @return 验签结果 true = 成功 false = 不成功
         * 
         * @see signByPriKey
         */
        public static boolean verifyByPubKey(Key pubKey, byte[] srcBytes,
                byte[] signBytes, String signAlg) {
            boolean result = false;
            try {
                Signature sign = Signature.getInstance(signAlg,
                        new BouncyCastleProvider());
                sign.initVerify((PublicKey) pubKey);
                sign.update(srcBytes);
                result = sign.verify(signBytes);
            } catch (NoSuchAlgorithmException e) {
                // LoggerUtil.error("公钥验签 - 无效算法:");
            } catch (InvalidKeyException e) {
                // LoggerUtil.error("公钥验签 - 无效的密钥:");
            } catch (SignatureException e) {
                // LoggerUtil.error("公钥验签 - 签名异常:");
            }
    
            return result;
        }
    
        /**
         * 从证书文件读取公钥
         * 
         * @param certFilePath
         *            公钥证书路径
         * @return 公钥
         */
        public static Key getPubKeyFromCertFile(String certFilePath) {
            PublicKey key = null;
            try {
                CertificateFactory factory = CertificateFactory
                        .getInstance("X.509");
                FileInputStream fis = new FileInputStream(certFilePath);
    
                X509Certificate cert = (X509Certificate) factory
                        .generateCertificate(fis);
                key = cert.getPublicKey();
            } catch (FileNotFoundException e) {
                // LoggerUtil.error("从证书文件读取公钥 - 证书文件不存在:");
                // LoggerUtil.error(e);
            } catch (CertificateException e) {
                // LoggerUtil.error("从证书文件读取公钥 - 密钥读取异常:");
                // LoggerUtil.error(e);
            }
    
            return key;
        }
    
        // /**
        // * 通过商户公钥证书验签
        // * @param certStr 证书信息,如certStyle = 1 则certStr即为证书base64内容,如certStyle=0
        // 则certStr即为证书保存路径
        // * @param certStyle 证书获取格式 1为从DB获取base64编码的证书文本。 2为从指定路径取证书文件
        // * @param srcMsg 签名源串
        // * @param signMsg 签名串
        // * @return
        // */
        // public static boolean verifyByCert(String certStr, int certStyle, String
        // srcMsg, String signMsg){
        //
        //
        // if(certStyle == 0){
        // try{
        // return verifyByPubKey(
        // getPubKeyFromStr(certStr),
        // srcMsg.getBytes("UTF-8"),
        // hexString2Bytes(signMsg),
        // SecurityUtil.MCHT_SIGN_ALG);
        // }catch(Exception e){
        // LoggerUtil.error(e);
        // return false;
        // }
        //
        // }else{
        // LoggerUtil.error("參数中指定了非法的证书存储格式");
        // return false;
        // }
        //
        // }
    
        /**
         * 使用公钥加密
         * 
         * @param pubKey
         *            公钥对象
         * @param plainText
         *            明文文本的字节数组
         * @param encAlg
         *            加密算法
         * @return 加密后的密文串
         * 
         * @see decByPriKey
         */
        public static byte[] encByPubKey(Key pubKey, byte[] plainText, String encAlg) {
            // 加密
            byte[] encBytes = null;
            try {
    
                Cipher cipher = Cipher.getInstance(encAlg,
                        new BouncyCastleProvider());
                cipher.init(Cipher.ENCRYPT_MODE, pubKey);
                encBytes = cipher.doFinal(plainText);
    
            } catch (NoSuchAlgorithmException e) {
                // LoggerUtil.error("公钥加密 - 无效算法:");
            } catch (InvalidKeyException e) {
                // LoggerUtil.error("公钥加密 - 无效密钥:");
            } catch (IllegalBlockSizeException e) {
                // LoggerUtil.error("公钥加密 - 非法的分块大小:");
            } catch (NoSuchPaddingException e) {
                // LoggerUtil.error("公钥加密 - 错误的填充格式:");
            } catch (BadPaddingException e) {
                // LoggerUtil.error("公钥加密 - 填充异常:");
            }
    
            return encBytes;
        }
    
    }
    

    package com.allinpay.user;
    
    import java.security.Key;
    import java.security.KeyPair;
    
    import com.allinpay.common.util.CertSignUtil;
    import com.allinpay.common.util.Constants;
    
    public class test {
    
        public static void main(String[] args) {
            KeyPair kp = CertSignUtil
                    .getKeyFromKeyStore("testMemberKey.keystore", "testMemberKey", "testMemberKey", "testMemberKey");
            Key pubKey = CertSignUtil.getPubKeyFromCertFile("TLCert4Sign_test.cer");
            System.out.println(pubKey);
            byte[] encBytes = CertSignUtil.encByPubKey(pubKey, "測试数据".getBytes(), "RSA");
            // System.out.println("aaaaaa" + new String(encBytes));
            byte[] aaa = CertSignUtil.signByPriKey(kp.getPrivate(), "測试数据".getBytes(), Constants.SHA1_WITH_RSA);
            System.out.println(aaa);
            String signMsg = CertSignUtil.bytes2HexString(aaa);
            System.out.println(signMsg);
    
            byte[] encByte = CertSignUtil.encByPubKey(pubKey, "測试数据".getBytes(), "RSA");
            String signMsg1 = CertSignUtil.bytes2HexString(encByte);
            System.out.println(signMsg1);
        }
    }
    

    java   RSA  默认的补码方式是  OPENSSL_PKCS1_PADDING  所以须要跟上面 php 代码部分一致。




  • 相关阅读:
    【PAT甲级】1043 Is It a Binary Search Tree (25 分)(判断是否为BST的先序遍历并输出后序遍历)
    Educational Codeforces Round 73 (Rated for Div. 2)F(线段树,扫描线)
    【PAT甲级】1042 Shuffling Machine (20 分)
    【PAT甲级】1041 Be Unique (20 分)(多重集)
    【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))
    【PAT甲级】1039 Course List for Student (25 分)(vector嵌套于map,段错误原因未知)
    Codeforces Round #588 (Div. 2)E(DFS,思维,__gcd,树)
    2017-3-9 SQL server 数据库
    2017-3-8 学生信息展示习题
    2017-3-5 C#基础 函数--递归
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6812103.html
Copyright © 2011-2022 走看看