`
zhaoshijie
  • 浏览: 2259868 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

非对称加密(RSA)加密解密实现通信JAVA端工具类(教程)

 
阅读更多
关键字:非对称加密(RSA)加密解密实现通信JAVA端工具类(教程)
近期的系统存在数据的交换,而且是异构系统的数据交换,所以需要实现.NET和Java的加密通信。研究和两三天终于把问题解决。现在提供了RSA的工具类,给之后需要实现的同行、同学一个参考。之后也会写一篇为什么.Net和Java之间的加密区别帮助大家理解代码。

Java端代码

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

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

public class RSASecurityUtil {
    private static final String KEY_ALGORITHM = "RSA";
    private static final int KEY_SIZE = 512;
    private static final int ENCRYPT_BlOCK_SIZE = KEY_SIZE / 8 - 11;
    private static final int DECRYPT_BLOCK_SIZE = KEY_SIZE / 8;

    public static KeyPair getKeyPair() throws Exception {
        KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        kpGenerator.initialize(KEY_SIZE);
        KeyPair keyPair = kpGenerator.generateKeyPair();
        return keyPair;
    }

    /**
     * 加密
     * @param encryptStr
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static String encrypt(String encryptStr,String publicKey) throws Exception{
        byte[] publicKeyBytes = Base64.decodeBase64(publicKey);
        byte[] encryptBytes = encryptStr.getBytes("UTF-8");
        
        if(encryptBytes.length <= ENCRYPT_BlOCK_SIZE){
            return Base64.encodeBase64String(encrypt(encryptBytes, publicKeyBytes));
        }else{
            byte[] buffer = null;
            byte[] blockBytes = new byte[ENCRYPT_BlOCK_SIZE];
            
            int index = ((encryptBytes.length - 1) / ENCRYPT_BlOCK_SIZE) + 1;
            
            for(int i = 0;i < index;i++){
                if(i == (index -1)){
                    blockBytes = new byte[ENCRYPT_BlOCK_SIZE];
                }              
                int startIndex = i * ENCRYPT_BlOCK_SIZE;
                int endIndex = startIndex + ENCRYPT_BlOCK_SIZE;
                blockBytes = ArrayUtils.subarray(encryptBytes,startIndex,endIndex);            
                if(buffer == null){
                    buffer = encrypt(blockBytes, publicKeyBytes);
                }else{
                    buffer = ArrayUtils.addAll(buffer, encrypt(blockBytes, publicKeyBytes));
                }
                
            }
            return Base64.encodeBase64String(buffer);
        }
    }

    /**
     * 解密
     * @param decryptStr
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String decryptStr,String privateKey) throws Exception{
        byte[] privateKeyBytes = Base64.decodeBase64(privateKey);
        
        byte[] decryptBytes = Base64.decodeBase64(decryptStr);
        
        if(decryptBytes.length <= DECRYPT_BLOCK_SIZE){
            return new String(decrypt(decryptBytes, privateKeyBytes),"UTF-8");
        }else{
            byte[] buffer = null;
                        
            int index = ((decryptBytes.length - 1) / DECRYPT_BLOCK_SIZE) + 1;
            byte[] blockBytes = new byte[DECRYPT_BLOCK_SIZE];
            for(int i = 0;i < index;i++){
                if(i == index -1){
                    blockBytes = new byte[DECRYPT_BLOCK_SIZE];
                }
                int startIndex = i * DECRYPT_BLOCK_SIZE;
                int endIndex = startIndex + DECRYPT_BLOCK_SIZE;
                blockBytes = ArrayUtils.subarray(decryptBytes,startIndex,endIndex > decryptBytes.length?decryptBytes.length:endIndex);
                if(buffer == null){
                    buffer = decrypt(blockBytes, privateKeyBytes);
                }else{
                    buffer = ArrayUtils.addAll(buffer, decrypt(blockBytes, privateKeyBytes));
                }
            }
            return new String(buffer,"UTF-8");
        }              
    }

    /**
     * 加密
     * @param encryptStr
     * @param publicKeyBytes
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] encryptBytes,byte[] publicKeyBytes) throws Exception{
        PublicKey publicKey = RSASecurityUtil.codeToPublicKey(publicKeyBytes);

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] enBytes = cipher.doFinal(encryptBytes);
        return enBytes;
    }

    /**
     * 解密
     * @param decryptStr
     * @param privateKeyBytes
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] decrypt,byte[] privateKeyBytes) throws Exception{
        PrivateKey privateKey = RSASecurityUtil.codeToPrivateKey(privateKeyBytes);

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        byte[] resultBytes = cipher.doFinal(decrypt);
        return resultBytes;
    }
    
    /**
     * 解密
     * @param dncrypteStr
     * @param privateKeyBytes
     * @return
     * @throws Exception
     */
    public static String decrypt(String decryptStr,byte[] privateKeyBytes) throws Exception{
        PrivateKey privateKey = RSASecurityUtil.codeToPrivateKey(privateKeyBytes);
        //加密/解密算法/工作模式/填充方式
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        byte[] decryptBytes = Base64.decodeBase64(decryptStr);
        byte[] resultBytes = cipher.doFinal(decryptBytes);
        return new String(resultBytes,"UTF-8");
    }

    public static String privateKeyToXml(PrivateKey key) {
        if (!RSAPrivateCrtKey.class.isInstance(key)) {
            return null;
        }
        RSAPrivateCrtKey priKey = (RSAPrivateCrtKey) key;

        StringBuilder sb = new StringBuilder();
        sb.append("<RSAKeyValue>");
        sb.append("<Modulus>").append(Base64.encodeBase64String(removeMSZero(priKey.getModulus().toByteArray()))).append("</Modulus>");
        sb.append("<Exponent>").append(Base64.encodeBase64String(removeMSZero(priKey.getPublicExponent().toByteArray()))).append("</Exponent>");
        sb.append("<P>").append(Base64.encodeBase64String(removeMSZero(priKey.getPrimeP().toByteArray()))).append("</P>");
        sb.append("<Q>").append(Base64.encodeBase64String(removeMSZero(priKey.getPrimeQ().toByteArray()))).append("</Q>");
        sb.append("<DP>").append(Base64.encodeBase64String(removeMSZero(priKey.getPrimeExponentP().toByteArray()))).append("</DP>");
        sb.append("<DQ>").append(Base64.encodeBase64String(removeMSZero(priKey.getPrimeExponentQ().toByteArray()))).append("</DQ>");
        sb.append("<InverseQ>").append(Base64.encodeBase64String(removeMSZero(priKey.getCrtCoefficient().toByteArray()))).append("</InverseQ>");
        sb.append("<D>").append(Base64.encodeBase64String(removeMSZero(priKey.getPrivateExponent().toByteArray()))).append("</D>");
        sb.append("</RSAKeyValue>");
        return sb.toString();
    }

    public static String publicKeyToXml(PublicKey key) {
        if (!RSAPublicKey.class.isInstance(key)) {
            return null;
        }
        RSAPublicKey pubKey = (RSAPublicKey) key;
        StringBuilder sb = new StringBuilder();

        sb.append("<RSAKeyValue>");
        sb.append("<Modulus>").append(Base64.encodeBase64String(removeMSZero(pubKey.getModulus().toByteArray()))).append("</Modulus>");
        sb.append("<Exponent>").append(Base64.encodeBase64String(removeMSZero(pubKey.getPublicExponent().toByteArray()))).append("</Exponent>");
        sb.append("</RSAKeyValue>");
        return sb.toString();
    }

    public static PublicKey codeToPublicKey(String publicKeyStr) throws Exception{
        byte[] publicKeyBytes = Base64.decodeBase64(publicKeyStr);
        //x.509,是x500那套网络协议(好像是目录协议吧)的一个子集,专门定义了在目录访问中需要身份认证的证书的格式。
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    public static PrivateKey codeToPrivateKey(String privateKeyStr) throws Exception{
        byte[] privateKeyBytes = Base64.decodeBase64(privateKeyStr);
        //PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey keyPrivate = keyFactory.generatePrivate(keySpec);
        return keyPrivate;
    }

    public static PublicKey codeToPublicKey(byte[] publicKey) throws Exception{
        //x.509,是x500那套网络协议(好像是目录协议吧)的一个子集,专门定义了在目录访问中需要身份认证的证书的格式。
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    public static PrivateKey codeToPrivateKey(byte[] privateKey) throws Exception{
        //PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey keyPrivate = keyFactory.generatePrivate(keySpec);
        return keyPrivate;
    }

    private static byte[] removeMSZero(byte[] data) {
        byte[] data1;
        int len = data.length;
        if (data[0] == 0) {
            data1 = new byte[data.length - 1];
            System.arraycopy(data, 1, data1, 0, len - 1);
        } else
            data1 = data;

        return data1;
    }

    public static void main(String[] args) throws Exception {
        KeyPair keyPair = RSASecurityUtil.getKeyPair();
        System.out.println("公钥:" + Base64.encodeBase64String(keyPair.getPublic().getEncoded()));
        System.out.println("私钥:" + Base64.encodeBase64String(keyPair.getPrivate().getEncoded()));
//        System.out.println("XML公钥:" + RSASecurityUtil.publicKeyToXml(keyPair.getPublic()));
//        System.out.println("XML私钥:" + RSASecurityUtil.privateKeyToXml(keyPair.getPrivate()));

//        String yw = "测试数据333“";
//        String mw = RSASecurityUtil.encrypt(yw,keyPair.getPublic().getEncoded());
//        String hw = RSASecurityUtil.dncrypte(mw,keyPair.getPrivate().getEncoded());

//        System.out.println("原文:" + yw);
//        System.out.println("密文:" + mw);
//        System.out.println("明文:" + hw);
        String wenjian = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<mainData>\n" +
        "<config>\n" +
        "     <operate>1</operate>                  <!--0:删除,1:新增,2:修改-->\n" +
        "</config>\n" +
        "<dataList type=\"personnel\">\n" +
        "     <data id=\"员工主数据主键\">            <!--默认主数据代码-->\n" +
        "       <code></code>                       <!--代码-->\n" +
        "       <name></name>                       <!--姓名-->\n" +
        "       <sex></sex>                         <!--性别-->\n" +
        "       <birthday></birthday>               <!--出生日期-->\n" +
        "       <education></education>             <!--文化程度-->\n" +
        "       <idNumber></idNumber>               <!--身份证号码-->\n" +
        "       <entryDate></entryDate>             <!--入职日期-->\n" +
        "       <departureDate></departureDate>     <!--离职日期-->\n" +
        "       <address></address>                 <!--住址-->\n" +
        "       <phoneNumber></phoneNumber>         <!--电话-->\n" +
        "       <mobilePhoneNumber></mobilePhoneNumber><!--移动电话-->\n" +
        "       <email></email>                     <!--电子邮件-->\n" +
        "       <position></position>               <!--职务-->\n" +
        "       <maritalStatus></maritalStatus>     <!--婚姻状况-->\n" +
        "       <partyAffiliation></partyAffiliation><!--政治面貌-->\n" +
        "       <username></username>               <!--用户名-->\n" +
        "       <sortNo></sortNo>                   <!--排序号-->\n" +
        "       <status></status>                   <!--状态-->\n" +
        "       <department></department>           <!--所属部门-->\n" +
        "       <company></company>                 <!--所属公司-->\n" +
        "    </data>\n" +
        "</dataList>\n" +
        "</mainData>";
//      Thread
        String mw = RSASecurityUtil.encrypt(wenjian, Base64.encodeBase64String(keyPair.getPublic().getEncoded()));
        String wm = RSASecurityUtil.decrypt(mw, Base64.encodeBase64String(keyPair.getPrivate().getEncoded()));
        
    }
}
分享到:
评论

相关推荐

    java编写的加密解密工具,有对称加密和非对称加密

    在Java中,我们可以使用`java.security`包中的`KeyPairGenerator`和`Cipher`类来实现RSA加密解密。 加密解密工具包通常会提供一个友好的接口,使得开发者可以方便地调用这些加密算法。例如,可能有一个`encrypt...

    unity工具类RSA加密和解密

    在Unity引擎中,RSA(Rivest-Shamir-Adleman)是一种广泛使用的非对称加密算法,常用于安全传输数据、数字签名等场景。本文将深入探讨RSA加密和解密的基础知识以及如何在Unity中实现这一功能。 首先,RSA加密的核心...

    JAVA中RSA加密解密工具类

    以下是一个简单的RSA加密解密工具类的实现: ```java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java....

    前端使用jsencrypt加密后端使用java RSA解密功能实现源码

    总结来说,这个功能实现的核心是使用RSA加密算法在前端进行数据加密,然后通过HTTP请求将加密数据发送到后端,后端使用Java的`RSAUtils`类进行解密。这种方法为前端与后端间的通信提供了安全保障,防止敏感数据在...

    c# rsa非对称加密与解密

    在C#中,我们可以使用.NET Framework提供的System.Security.Cryptography命名空间中的RSACryptoServiceProvider类来实现RSA加密和解密。首先,我们需要生成一对密钥,这可以通过RSACryptoServiceProvider的Generate...

    RSA sha-256加密解密,加签验签工具类

    RSA是一种非对称加密算法,它是公钥密码学的基础,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出。该算法基于大数因子分解的困难性,使得只有拥有特定密钥的人才能解密信息。SHA-256则是SHA-2(安全哈希...

    RSA+AES 加密工具类 Java

    在这个“RSA+AES加密工具类 Java”中,我们将深入探讨这两种加密技术以及如何在Java环境中,包括Android和Web应用,实现它们。 首先,RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,基于大整数因子分解的困难...

    对称加密 非对称加密 需要的jar包

    在Java中,`java.security`包提供了实现非对称加密的接口和类,如`KeyPairGenerator`用于生成密钥对,`Cipher`用于加解密操作。 在上述的【压缩包子文件的文件名称列表】中,我们看到两个重要的库: 1. **bcprov-...

    RSA2--》加签+加密+解密+验签

    RSA算法是一种非对称加密算法,它在信息安全领域有着广泛的应用,特别是在数字签名、数据加密和安全通信中。本文将详细讲解RSA算法的加签、加密、解密以及验签的过程,结合Java语言来实现这一系列操作,并涉及到证书...

    Java实现RSA加解密工具类Demo

    Java实现RSA加解密工具类Demo是一个典型的非对称加密技术的应用示例,RSA是一种广泛使用的公开密钥加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出。它基于大数因子分解的困难性,提供了安全的...

    C#RSA加密解密工具

    C# RSA加密解密工具是一种基于公钥/私钥对的加密算法实现,主要用于保障数据的安全传输和存储。RSA(Rivest-Shamir-Adleman)算法是公开密钥加密技术的鼻祖,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出...

    aes、ras,前端js加密,后端java解密

    `AesUtils.java`可能包含了处理AES加密的工具类,包括创建密钥、加密和解密方法。`RSACoder.java`则是处理RSA加密/解密的类,可能包含了生成公钥和私钥、解密前端传来的RSA加密数据等功能。 **工作流程** 1. **前端...

    C# .net版 RSA 公钥加密私钥解密 私钥加密公钥解密

    RSA是一种非对称加密算法,它基于数学难题的大数因子分解,由Ron Rivest、Adi Shamir和Leonard Adleman于1977年提出,因此得名RSA。本教程主要讲解如何在C# .NET环境中使用RSA进行公钥加密和私钥解密,以及私钥加密...

    RSA 通用加密、解密工具类(JAVA)

    这个Java实现的RSA工具类提供了生成密钥对、公钥加密和私钥解密的功能,对于理解和使用RSA算法非常有帮助。下面将详细介绍这些功能以及相关知识点。 首先,RSA算法基于两个大素数的乘积难以因式分解这一数学难题。...

    java实现非对称加密

    在 Java 中,可以使用 RSA 算法实现非对称加密。 RSA 算法是最常用的非对称加密算法之一。它的安全性取决于密钥的长度和安全性。 Java 中的 RSA 加密可以分为以下步骤: 1. 生成公钥和私钥:使用 KeyPairGenerator...

    C# RSA加密、支持JAVA格式公钥私钥

    综上所述,这个C#项目旨在提供一个与Java平台兼容的RSA加密解密工具,方便跨平台的数据安全传输。开发人员可以利用这个工具包,使用C#进行RSA操作,同时处理来自Java环境的公钥和私钥。这在多语言协作或者混合系统...

    vue生成rsa非对称加密工具类及使用方法(包含公钥加密,私钥解密)

    RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不...

    用C#实现RSA的加密与解密

    总结起来,用C#实现RSA加密与解密涉及了非对称加密原理、`RSACryptoServiceProvider`类的使用、密钥生成与管理、以及可能的用户界面设计。在实际应用中,这些知识可以用于保障数据安全,实现安全的通信和存储。

    Java RSA 加密/解密/签名 工具类

    Java RSA 加密/解密/签名工具类是Java开发中常用的一种安全技术实现,主要用于数据的保护和身份验证。RSA是一种非对称加密算法,基于大整数因子分解的困难性,提供了加密、解密以及数字签名的功能。下面将详细介绍...

    RSA加解密的JAVA实现

    RSA算法是一种广泛应用于网络安全的非...总之,RSA算法在Java中的实现涉及了非对称加密的核心原理,包括密钥对的生成、加密解密过程,以及可能的用户界面设计。理解这些概念对于深入学习网络安全和Java编程都至关重要。

Global site tag (gtag.js) - Google Analytics