• Java RSA加密以及验签


    签名加密以及验签工具类:

    一般秘钥分为3个key

    1.自己生成的私钥,

    2.通过私钥生成的公钥1

    3.通过提交公钥1给某宝,获取的公钥2。

    RSA公钥加密算法简介
    非对称加密算法。只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
    目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

    一般使用私钥对请求参数加密生成签名,并且使用公钥2来验证支付回调的签名,RSA签名加密解密工具类如下:

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    import javax.crypto.Cipher;
    
    public class RSA {
    	
    public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
    	
    	private final static Logger log =Logger.getLogger(RSA.class); 
    
    	/**
    	* RSA签名
    	* @param content 待签名数据
    	* @param privateKey 商户私钥
    	* @param input_charset 编码格式
    	* @return 签名值
    	*/
    	public static String sign(String content, String privateKey, String input_charset)
    	{
            try 
            {
            	PKCS8EncodedKeySpec priPKCS8 	= new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); 
            	KeyFactory keyf 				= KeyFactory.getInstance("RSA");
            	PrivateKey priKey 				= keyf.generatePrivate(priPKCS8);
    
                java.security.Signature signature = java.security.Signature
                    .getInstance(SIGN_ALGORITHMS);
    
                signature.initSign(priKey);
                signature.update( content.getBytes(input_charset) );
    
                byte[] signed = signature.sign();
                
                return Base64.encode(signed);
            }
            catch (Exception e) 
            {
            	log.error(e.getMessage(), e);
            }
            
            return null;
        }
    	
    	/**
    	* RSA验签名检查
    	* @param content 待签名数据
    	* @param sign 签名值
    	* @param ali_public_key 支付宝公钥
    	* @param input_charset 编码格式
    	* @return 布尔值
    	*/
    	public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
    	{
    		try 
    		{
    			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    	        byte[] encodedKey = Base64.decode(ali_public_key);
    	        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    
    		
    			java.security.Signature signature = java.security.Signature
    			.getInstance(SIGN_ALGORITHMS);
    		
    			signature.initVerify(pubKey);
    			signature.update( content.getBytes(input_charset) );
    		
    			boolean bverify = signature.verify( Base64.decode(sign) );
    			return bverify;
    			
    		} 
    		catch (Exception e) 
    		{
    			log.error(e.getMessage(), e);
    		}
    		
    		return false;
    	}
    	
    	/**
    	* 解密
    	* @param content 密文
    	* @param private_key 商户私钥
    	* @param input_charset 编码格式
    	* @return 解密后的字符串
    	*/
    	public static String decrypt(String content, String private_key, String input_charset) throws Exception {
            PrivateKey prikey = getPrivateKey(private_key);
    
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, prikey);
    
            InputStream ins = new ByteArrayInputStream(Base64.decode(content));
            ByteArrayOutputStream writer = new ByteArrayOutputStream();
            //rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
            byte[] buf = new byte[128];
            int bufl;
    
            while ((bufl = ins.read(buf)) != -1) {
                byte[] block = null;
    
                if (buf.length == bufl) {
                    block = buf;
                } else {
                    block = new byte[bufl];
                    for (int i = 0; i < bufl; i++) {
                        block[i] = buf[i];
                    }
                }
    
                writer.write(cipher.doFinal(block));
            }
    
            return new String(writer.toByteArray(), input_charset);
        }
    
    	
    	/**
    	* 得到私钥
    	* @param key 密钥字符串(经过base64编码)
    	* @throws Exception
    	*/
    	public static PrivateKey getPrivateKey(String key) throws Exception {
    
    		byte[] keyBytes;
    		
    		keyBytes = Base64.decode(key);
    		
    		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
    		
    		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    		
    		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
    		
    		return privateKey;
    	}
    
    }
    

      

  • 相关阅读:
    spoj 694 求一个字符串中不同子串的个数
    Qt for Android 开发大坑
    HDUOJ A Mathematical Curiosity 1017
    Node.js开发入门—HelloWorld再分析
    GTK入门学习:布局容器之固定布局
    彻底领悟javascript中的exec与match方法
    JQuery中attr属性和jQuery.data()学习笔记
    正则表达式-验证带千分号的,带任意位小数的数字类型
    JQuery EasyUI 动态改变表单项的验证守则
    JavaScript计算两个日期的时间差
  • 原文地址:https://www.cnblogs.com/wangzun/p/8885547.html
Copyright © 2020-2023  润新知