zoukankan      html  css  js  c++  java
  • RSAUtils

    package com.xxx.common.utils;

    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.lang3.ArrayUtils;

    import javax.crypto.Cipher;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;

    public class RSAUtils {
    private static final String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMBMrifYyHbyMvBOuUujkC55GgWo1zntp4pjBisqGOHTu4QLLMBFogWwr1khZUXkgJEOOJxyhso7twEARaYdvGo6jB2ZMlByNBgg4Lk2+Xyqcn9Zh0MZD5n3KwXDUFmI/GkwI9X5Bo7IRyvaPFqxTvo7kWsuqyxu7B4RIq4xfQLwIDAQAB";
    private static final String privateKeyStr = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIwEyuJ9jIdvIy8E65S6OQLnkaBajXOe2nimMGKyoY4dO7hAsswEWiBbCvWSFlReSAkQ44nHKGyju3AQBFph28ajqMHZkyUHI0GCDguTb5fKpyf1mHQxkPmfcrBcNQWYj8aTAj1fkGjshHK9o8WrFO+juRay6rLG7sHhEirjF9AvAgMBAAECgYA3IlP5Z1KEqeCCzT8uaz2zxRd0uvNkCbMhOt9mncw7t4sifGdrKnOKtg7Ur9eXFSDsYPgX8pIaZUaTU9tC87GkJ1+bT4EkxgCuKHCeASs6OQBMLGXaXxyJY0ZIIJFAjrmm0KUvh0qAOmIuamo63rMhQXSYVOuWiwJ0jCVcnFbR8QJBAOwlax1/Z8s6XWpD2/GW39Wbm6HCKP1mrHtZYaOB+xHRGIm2NClcISlmpAzlw1++SibVqN+L2mZ4KgESUe3iOaUCQQCXymuELq38OkZFjcSOVM5f4VYJkwwVAcM2eWuKhGe3eH0+9xPwzWmzQos1HFE1wI39tpeI7ihJrTfXfSG8NrJDAkA/5mgz1TP69FIu3Sn5F8B+Btt4TBfXah8mSat4GUYdLh2btigrQPjgQRwHOW1CzTU3iP1ncGqq671CCPkOi/bZAkBblMib3uIgXTSKwIdH7Mj7NmSHsE3I2uBiHI4S6+H741mFxOMmFXlhq5N7/tLMoJnK6wCwoCh0k2suu5PAECwrAkAgTOy4ty0ZUOme+N4cGOLAACfUHhJi8PaFSrFFl35PgzQRt6jS8LLiqFeaM7IiaGEop2wSLKoyeSoe1WOQSb33";

    // public static void main( String[] args ) throws Exception {
    // //生成公钥和私钥
    // getKeyPair();
    // //加密字符串
    // String password="<p><div style=\"text-align: center;\"><img src=\"https://img.eoliao.com/b60a6c68-0118-4758-bde2-c9e69394168b.jpg\" style=\"font-family: &quot;Microsoft Yahei&quot;, sans-serif; font-size: 14px; text-align: initial; max- 100%;\"></div>国际米兰主帅孔蒂希望今夏能够大幅度补强中场,目前蓝黑军团基本上已经敲定了比达尔的加盟,接下来他们还希望签下另外一名强援——坎特。《米兰体育报》的最新消息表示,坎特本人十分愿意加盟到国际米兰,但是切尔西方面希望得到至少5000万欧元的转会费。<br><br>《米兰体育报》称,孔蒂一直以来都十分欣赏坎特,在他执教切尔西期间,法国国脚便是他的爱将,在执教国际米兰之后,孔蒂也曾多次希望将坎特引进到阵中。这个夏天的转会窗开启之后,孔蒂便将坎特视作中场引援的头号目标,并且他也已经亲自说服坎特转投蓝黑军团,接下来的事情便是国际米兰高层去说服切尔西高层放人了。<br><div style=\"text-align: center;\"><img src=\"https://img.eoliao.com/768ad2a3-f04f-4c70-9f8c-32d66137a50e.jpg\" style=\"font-family: &quot;Microsoft Yahei&quot;, sans-serif; font-size: 14px; text-align: initial; max- 100%;\"></div>据了解,目前国际米兰高层已经开始与切尔西方面进行接触,但暂时来看情况不是很乐观。因为切尔西对于坎特的标价高达5000万欧元,这已经明显超出了国际米兰方面的预期。当然了,考虑到孔蒂强烈要求得到坎特的意愿,国际米兰方面还是打算满足切尔西的要价,但前提是他们要通过卖人来募集转会资金。<br><br>在目前的国际米兰阵中,有包括布罗佐维奇、什克里尼亚尔以及埃里克森几名重量级球员属于可出售的范围。此前曾有消息称国际米兰希望用埃里克森与坎特进行互换,但是切尔西方面对此提议并不感兴趣。而布罗佐维奇目前则吸引到了摩纳哥的关注,但是前法甲冠军也满足不了国际米兰2200万欧元的要价。<br><div style=\"text-align: center;\"><img src=\"https://img.eoliao.com/e6527cdd-ef42-4397-b736-6f0ee3927456.jpg\" style=\"font-family: &quot;Microsoft Yahei&quot;, sans-serif; font-size: 14px; text-align: initial; max- 100%;\"></div>《米兰体育报》最后还透露,如果国际米兰最终无法说服切尔西放人,那么他们会转攻其他目标,目前马竞后腰托马斯被蓝黑军团视作第二选择。不过要想说服马竞放人同样难度很大,个中原因其实也是因为钱,床单军团为托马斯标出的价格同样是5000万欧元,国际米兰还是难以支付这个价格。</p>";
    // System.out.println("随机生成的公钥为:"+keyMap.get(0));
    // System.out.println("随机生成的私钥为:"+keyMap.get(1));
    // String passwordEn=encrypt(password,keyMap.get(0));
    // System.out.println(password+"\t加密后的字符串为:"+passwordEn);
    // String passwordDe=decrypt(passwordEn,keyMap.get(1));
    // System.out.println("还原后的字符串为:"+passwordDe);
    // }
    // /**
    // * 随机生成密钥对
    // * @throws NoSuchAlgorithmException
    // */
    public static void getKeyPair() throws Exception {
    //KeyPairGenerator类用于生成公钥和密钥对,基于RSA算法生成对象
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
    //初始化密钥对生成器,密钥大小为96-1024位
    keyPairGen.initialize(1024,new SecureRandom());
    //生成一个密钥对,保存在keyPair中
    KeyPair keyPair = keyPairGen.generateKeyPair();
    PrivateKey privateKey = keyPair.getPrivate();//得到私钥
    PublicKey publicKey = keyPair.getPublic();//得到公钥
    //得到公钥字符串
    String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
    System.out.println(publicKeyString);
    //得到私钥字符串
    String privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()));
    System.out.println(privateKeyString);
    }

    /**
    * RSA最大加密明文大小
    */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
    * RSA最大解密密文大小
    */
    private static final int MAX_DECRYPT_BLOCK = 128;

    public static final String SIGN_ALGORITHMS = "SHA256withRSA";

    private static String ALGORITHM_RSA = "RSA";

    /**
    * 使用公钥将数据加密
    * @param sourceData
    * @param publicKey
    * @return
    */
    public static String publicEncrypt(String sourceData, String publicKey){
    return rsaEncrypt(sourceData,publicKey,false);
    }

    /**
    * 使用私钥将数据加密
    * @param sourceData
    * @param privateKey
    * @return
    */
    public static String privateEncrypt(String sourceData, String privateKey){
    return rsaEncrypt(sourceData,privateKey,true);
    }

    /**
    * 使用公钥解密
    * @param encryptedData
    * @param privateKey
    * @return
    */
    public static String publicDecrypt(String encryptedData, String privateKey) {
    return rsaDecrypt(encryptedData,privateKey,false);
    }

    /**
    * 使用私钥解密
    * @param encryptedData
    * @param privateKey
    * @return
    */
    public static String privateDecrypt(String encryptedData, String privateKey) {
    return rsaDecrypt(encryptedData,privateKey,true);
    }

    protected static String rsaEncrypt(String sourceData, String key,boolean isPrivate){
    try {
    Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);
    byte[] data = sourceData.getBytes();
    byte[] dataReturn = new byte[0];
    Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
    cipher.init(Cipher.ENCRYPT_MODE, key1);

    // 加密时超过117字节就报错。为此采用分段加密的办法来加密
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) {
    byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,i + MAX_ENCRYPT_BLOCK));
    sb.append(new String(doFinal));
    dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
    }

    return Base64.encodeBase64URLSafeString(dataReturn);
    } catch (Exception e) {
    e.printStackTrace();
    return null;
    }
    }

    protected static String rsaDecrypt(String encryptedData, String key,boolean isPrivate){
    try {
    Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);
    byte[] data = Base64.decodeBase64(encryptedData);

    Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
    cipher.init(Cipher.DECRYPT_MODE, key1);

    // 解密时超过128字节就报错。为此采用分段解密的办法来解密
    byte[] dataReturn = new byte[0];
    for (int i = 0; i < data.length; i += MAX_DECRYPT_BLOCK) {
    byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_DECRYPT_BLOCK));
    dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
    }

    return new String(dataReturn);
    } catch (Exception e) {
    e.printStackTrace();
    return null;
    }
    }

    /**
    * 私钥加签名
    * @param encryptData
    * @param privateKey
    * @return
    */
    public static String rsaSign(String encryptData, String privateKey) {
    try {
    Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
    signature.initSign(loadPrivateKey(privateKey));
    signature.update(encryptData.getBytes());
    byte[] signed = signature.sign();
    return Base64.encodeBase64URLSafeString(signed);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }

    /**
    * 公钥验签
    * @param encryptStr
    * @param sign
    * @param publicKey
    * @return
    * @throws Exception
    */
    public static boolean verifySign(String encryptStr, String sign, String publicKey)throws Exception {
    try {
    Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
    signature.initVerify(loadPublicKey(publicKey));
    signature.update(encryptStr.getBytes());
    return signature.verify(Base64.decodeBase64(sign));
    } catch (NoSuchAlgorithmException e) {
    throw new Exception(String.format("验证数字签名时没有[%s]此类算法", SIGN_ALGORITHMS));
    } catch (InvalidKeyException e) {
    throw new Exception("验证数字签名时公钥无效");
    } catch (SignatureException e) {
    throw new Exception("验证数字签名时出现异常");
    }
    }

    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
    byte[] buffer = Base64.decodeBase64(publicKeyStr);
    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
    return keyFactory.generatePublic(keySpec);
    }

    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
    byte[] buffer = Base64.decodeBase64(privateKeyStr);
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
    return keyFactory.generatePrivate(keySpec);
    }

    public static String urlsafe_encode (String encryptStr){
    return encryptStr.replaceAll("\\+","-").replaceAll("/","_").replaceAll("=","").replaceAll("(\r\n|\r|\n|\n\r)","");

    }

    public static String urlsafe_decode(String encryptStr){
    encryptStr= encryptStr.replaceAll("-","+").replaceAll("_","/");
    int mob = encryptStr.length()%4;
    if(mob>0){
    encryptStr+="====".substring(mob);
    }
    return encryptStr;
    }



    public static void main(String[ ] asdfs) throws Exception {
    getKeyPair();

    //加密
    String data = "<p><div style=\"text-align: center;\"><img src=\"https://img.eoliao.com/b60a6c68-0118-4758-bde2-c9e69394168b.jpg\" style=\"font-family: &quot;Microsoft Yahei&quot;, sans-serif; font-size: 14px; text-align: initial; max- 100%;\"></div>国际米兰主帅孔蒂希望今夏能够大幅度补强中场,目前蓝黑军团基本上已经敲定了比达尔的加盟,接下来他们还希望签下另外一名强援——坎特。《米兰体育报》的最新消息表示,坎特本人十分愿意加盟到国际米兰,但是切尔西方面希望得到至少5000万欧元的转会费。<br><br>《米兰体育报》称,孔蒂一直以来都十分欣赏坎特,在他执教切尔西期间,法国国脚便是他的爱将,在执教国际米兰之后,孔蒂也曾多次希望将坎特引进到阵中。这个夏天的转会窗开启之后,孔蒂便将坎特视作中场引援的头号目标,并且他也已经亲自说服坎特转投蓝黑军团,接下来的事情便是国际米兰高层去说服切尔西高层放人了。<br><div style=\"text-align: center;\"><img src=\"https://img.eoliao.com/768ad2a3-f04f-4c70-9f8c-32d66137a50e.jpg\" style=\"font-family: &quot;Microsoft Yahei&quot;, sans-serif; font-size: 14px; text-align: initial; max- 100%;\"></div>据了解,目前国际米兰高层已经开始与切尔西方面进行接触,但暂时来看情况不是很乐观。因为切尔西对于坎特的标价高达5000万欧元,这已经明显超出了国际米兰方面的预期。当然了,考虑到孔蒂强烈要求得到坎特的意愿,国际米兰方面还是打算满足切尔西的要价,但前提是他们要通过卖人来募集转会资金。<br><br>在目前的国际米兰阵中,有包括布罗佐维奇、什克里尼亚尔以及埃里克森几名重量级球员属于可出售的范围。此前曾有消息称国际米兰希望用埃里克森与坎特进行互换,但是切尔西方面对此提议并不感兴趣。而布罗佐维奇目前则吸引到了摩纳哥的关注,但是前法甲冠军也满足不了国际米兰2200万欧元的要价。<br><div style=\"text-align: center;\"><img src=\"https://img.eoliao.com/e6527cdd-ef42-4397-b736-6f0ee3927456.jpg\" style=\"font-family: &quot;Microsoft Yahei&quot;, sans-serif; font-size: 14px; text-align: initial; max- 100%;\"></div>《米兰体育报》最后还透露,如果国际米兰最终无法说服切尔西放人,那么他们会转攻其他目标,目前马竞后腰托马斯被蓝黑军团视作第二选择。不过要想说服马竞放人同样难度很大,个中原因其实也是因为钱,床单军团为托马斯标出的价格同样是5000万欧元,国际米兰还是难以支付这个价格。</p>";
    String privateEncryptStr = RSAUtils.privateEncrypt(data, privateKeyStr);//私钥加密
    String publicEncryptStr = RSAUtils.publicEncrypt(data, publicKeyStr);//公钥加密
    // String privateEncryptSign = RSAUtils.rsaSign(privateEncryptStr,privateKeyStr);
    // String publicEncryptSign = RSAUtils.rsaSign(publicEncryptStr,privateKeyStr);
    System.out.println("source:" + data);
    // System.out.println("private encryptStr: " + privateEncryptStr);
    // System.out.println("public encryptStr: " + publicEncryptStr);
    // System.out.println("private encrypt sign: " + privateEncryptSign);
    // System.out.println("public encrypt sign: " + publicEncryptSign);
    //
    // System.out.println("public decrypt:" + RSAUtils.publicDecrypt(privateEncryptStr, publicKeyStr));
    // System.out.println("private decrypt:" + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
    // System.out.println("verifySign1: " + RSAUtils.verifySign(privateEncryptStr,privateEncryptSign,publicKeyStr));
    // System.out.println("verifySign2: " + RSAUtils.verifySign(publicEncryptStr,publicEncryptSign,publicKeyStr));
    //
    // System.out.println("\r\n");
    // publicEncryptStr = "WopnO2LnolZ7XpOwA_ktOhfkkaQQJQgkJudk3ZH_-ob36GQFv968nE1UBXxNekA9pIHBcvcl0ZWfwFhk-kyOF2FmQvpPY9LkqiCV0T32vhJet0n93ti2PBoFILxvChjzdOgSG9M0flH78Vm696Q4mHo7VMt_XMoHDTd3Rbagvt8";
    // privateEncryptStr = "Fwb5BtLRveCWbx7FkXarl1zVOdwDvbDTl7gv-vPHXpj-T2wm9GlUDn3X0wnHHXkE8cqAT6PcE0g0ide6beP9_ysHMLgnC6wVqkomIKsi6C9TcGd4d6XQBjeJgdgccvDcD-7pcKrV9W-_Z7jkYkwwrjPGPd_uckEHR_cDXyOX4PU";
    // System.out.println("php >>>> private decrypt: " + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
    // System.out.println("php >>>> public decrypt: " + RSAUtils.publicDecrypt(privateEncryptStr, publicKeyStr));
    //
    // publicEncryptStr = "T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0";
    // System.out.println("js >>>> private decrypt: " + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
    }
    }
  • 相关阅读:
    android数据恢复
    UVA 690 Pipeline Scheduling
    2017 国庆湖南 Day4
    2017 国庆湖南 Day5
    2017 国庆湖南 Day6
    2017国庆 清北学堂 北京综合强化班 Day1
    2017 国庆湖南Day2
    bzoj 2962 序列操作
    UVA 818 Cutting Chains
    UVA 211 The Domino Effect
  • 原文地址:https://www.cnblogs.com/michaelcnblogs/p/15735984.html
Copyright © 2011-2022 走看看