`
ispring
  • 浏览: 359448 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

使用RSA加密算法对文件进行非对称加密

阅读更多
package com.ivan.security.algorithm;

/**
 * RSA加密算法的使用
 * @author Ivan
 * @DataTime 2006-12-12 16:38
 * Java 本身不提供 RSA 算法的支持
 * 需下载 assembla_msks_jce.ar 或 bcprov-jdk14-123.jar 包
 */

/**
 * RSA加密原理概述
 * RSA的安全性依赖于大数的分解,公钥和私钥都是两个大素数(大于100的十进制位)的函数。
 * 据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积
 * ===================================================================
 * (该算法的安全性未得到理论的证明)
 * ===================================================================
 * 密钥的产生:
 * 1.选择两个大素数 p,q ,计算 n=p*q;
 * 2.随机选择加密密钥 e ,要求 e 和 (p-1)*(q-1)互质
 * 3.利用 Euclid 算法计算解密密钥 d , 使其满足 e*d = 1(mod(p-1)*(q-1)) (其中 n,d 也要互质)
 * 4:至此得出公钥为 (n,e) 私钥为 (n,d)
 * ===================================================================
 * 加解密方法:
 * 1.首先将要加密的信息 m(二进制表示) 分成等长的数据块 m1,m2,...,mi 块长 s(尽可能大) ,其中 2^s<n
 * 2:对应的密文是: ci = mi^e(mod n)
 * 3:解密时作如下计算: mi = ci^d(mod n)
 * ===================================================================
 * RSA速度
 * 由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论 是软件还是硬件实现。
 * 速度一直是RSA的缺陷。一般来说只用于少量数据 加密。
 */

import javax.crypto.Cipher;

import com.iuxi.security.util.Tool;

import java.security.*;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.interfaces.RSAPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.math.BigInteger;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;

import se.assembla.jce.provider.ms.MSProvider;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class RSAUtil ...{
    
    public static RSAPublicKey pubKey;
    public static RSAPrivateKey priKey;
    
    public static void init() ...{
        Security.insertProviderAt(new MSProvider(), 2);
    }
    
    public static boolean saveKeys(String pubfile, String prifile) ...{
        try ...{
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(pubfile));
            oos.writeObject(pubKey);
            oos = new ObjectOutputStream(new FileOutputStream(prifile));
            oos.writeObject(priKey);
            oos.close();
            return true;
        }catch(IOException e) ...{
            System.err.println("保存密钥失败!");
            e.printStackTrace();
        }
        return false;
    }
    
    public static boolean readKeys(String pubfile, String prifile) ...{
        try ...{
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pubfile));
            pubKey = (RSAPublicKey)ois.readObject();
            ois = new ObjectInputStream(new FileInputStream(prifile));
            priKey = (RSAPrivateKey)ois.readObject();
            return true;
        }catch(IOException e) ...{
            System.err.println("读取密钥失败!");
            e.printStackTrace();
        }catch(Exception e) ...{
            e.printStackTrace();
        }
        return false;
    }
    
    /** *//**
     * 生成密钥对
     * @return 返回该密钥对 KeyPair
     * @throws Exception 指定的算法无效
     */
    public static KeyPair genKeyPair() throws Exception ...{
        try ...{
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            final int KEY_SIZE = 1024;
            keyPairGen.initialize(KEY_SIZE,new SecureRandom());
            KeyPair keyPair = keyPairGen.genKeyPair();
            pubKey = (RSAPublicKey)keyPair.getPublic();
            priKey = (RSAPrivateKey)keyPair.getPrivate();
            return keyPair;
        }catch(NoSuchAlgorithmException e) ...{
            System.err.println("生成密钥对错误,无效算法!");
            throw new Exception(e.getMessage());
        }
    }
    
    /** *//**
     * 生成加密用的公钥
     * @param module 系数
     * @param publicExponent 公用指数
     * @return 生成的公钥
     * @throws Exception 指定的算法无效
     */
    public static RSAPublicKey genRSAPublicKey(byte[] module, byte[] publicExponent) throws Exception ...{
        System.out.println("正在生成公钥...");
        try ...{
            KeyFactory keyFac = null;
            keyFac = KeyFactory.getInstance("RSA");
            RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(module),new BigInteger(publicExponent));
            pubKey = (RSAPublicKey)keyFac.generatePublic(pubKeySpec);
            return pubKey;
        }catch(NoSuchAlgorithmException e) ...{
            System.err.println("生成公钥错误,无效算法!");
            throw new Exception(e.getMessage());
        }catch(InvalidKeySpecException e) ...{
            throw new Exception(e.getMessage());
        }
    }
    
    /** *//**
     * 生成加密用的私钥
     * @param module 系数
     * @param privateExponent 公用指数
     * @return 生成的私钥
     * @throws Exception 指定的算法无效
     */
    public static RSAPrivateKey genRSAPrivateKey(byte[] module, byte[] privateExponent) throws Exception ...{
        System.out.println("正在生成私钥...");
        try ...{
            KeyFactory keyFac = KeyFactory.getInstance("RSA");
            RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(module), new BigInteger(privateExponent));
            priKey = (RSAPrivateKey)keyFac.generatePrivate(priKeySpec);
            return priKey;
        }catch(NoSuchAlgorithmException e) ...{
            System.err.println("生成私钥错误,无效算法");
            throw new Exception(e.getMessage());
        }
    }
    
    /** *//**
     * 对 byte[] 类型数据进行加密
     * @param data 原始数据
     * @return cipherData 加密后的数据
     * @throws Exception
     */
    public static byte[] encryptData(byte[] rawData) throws Exception ...{
        if(pubKey == null) ...{
            System.err.println("加密失败,原因:加密密钥不存在!");
            return null;
        }
        try ...{
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            
            int blockSize = cipher.getBlockSize();    //获取加密数据块的大小
            int outputSize = cipher.getOutputSize(rawData.length);    //获取加密后数据块的大小
            int leavedSize = rawData.length % blockSize;
            int blocksNum = (leavedSize == 0)?(rawData.length / blockSize):(rawData.length / blockSize +1);    //获取加密块数
            byte[] cipherData = new byte[outputSize * blocksNum];
//            System.err.println("rawData.length = " + rawData.length);
//            System.err.println("cipherData.length = " + cipherData.length);
//            System.err.println("blockSize = " + blockSize);
//            System.err.println("outputSize = " + outputSize);
//            System.err.println("blocksNum = " + blocksNum);
            
            //对每块数据分别加密
//            for(int i=0; i<blocksNum; i++) {
//                System.err.println(i + " * blockSize = " + (i * blockSize));
//                System.err.println(i + " * outputSize = " + (i * outputSize));
//                System.err.println("rawData.length - " + i + " * blockSize = " + (rawData.length - i * blockSize));
//                if((rawData.length - i * blockSize) > blockSize)
//                    cipher.doFinal(rawData, i * blockSize, blockSize, cipherData);
//                else
//                    cipher.doFinal(rawData, i * blockSize, rawData.length - i * blockSize, cipherData);
//            }
            cipherData = cipher.doFinal(rawData);
            return cipherData;
        }catch(Exception e) ...{
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }
    
    /** *//**
     * 解密 cipherData 为明文
     * @param cipherData 原始密文
     * @return 解密后的明文
     * @throws Exception
     */
    public static byte[] decryptData(byte[] cipherData) throws Exception ...{
        System.out.println("正在解密数据...");
        if(priKey == null) ...{
            System.err.println("解密失败,原因:解密密钥不存在!");
            return null;
        }
        try ...{
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(cipher.DECRYPT_MODE, priKey);
            int blockSize = cipher.getBlockSize();
//            System.err.println("Decrypt: BlockSize = " + blockSize);
//            System.err.println("Decrypt: CipherLength = " + cipherData.length);
            ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
            int j = 0;
            
            //分别对各块数据进行解密
            while((cipherData.length - j * blockSize) > 0) ...{
                bout.write(cipher.doFinal(cipherData, j * blockSize, blockSize));
                j++;
            }
            return bout.toByteArray();
        }catch(Exception e) ...{
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }
    
    public static void main(String[] args) throws Exception...{
        
        byte[] rawData = Tool.readRawData("Order.xml");
        RSAUtil.init();
        KeyPair keyPair = RSAUtil.genKeyPair();
        if(RSAUtil.saveKeys("RSAPubKey.dat", "RSAPriKey.dat"));
        else
            System.err.println("保存密钥失败...");
        
//        byte[] pubModBytes = pubKey.getModulus().toByteArray();
//        byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
//        byte[] priModBytes = priKey.getModulus().toByteArray();
//        byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
//        
//        RSAPublicKey recoveryPubKey = RSA.genRSAPublicKey(pubModBytes, pubPubExpBytes);
//        System.out.println("生成恢复性RSA公钥成功");
//        RSAPrivateKey recoveryPriKey = RSA.genRSAPrivateKey(priModBytes, priPriExpBytes);
//        System.out.println("生成恢复性RSA私钥成功");
        
        byte[] cipherData = RSAUtil.encryptData(rawData);
        String cipher = new String();
        cipher = new BASE64Encoder().encode(cipherData);
        System.err.println(cipher);
//        System.out.println("加密后的密文为:" + Tool.byte2hex(cipherData));
//        System.out.println("加密成功");
        rawData = RSAUtil.decryptData(new BASE64Decoder().decodeBuffer(cipher));
        System.out.println("解密后的明文为:  " + new String(rawData));
    }
}

 

分享到:
评论
12 楼 zpchen 2009-05-05  
[color=red]楼主这样贴代码出来有什么用啊[/color]

又没有jar,又没有Tool
贴出来花这么多时间看,又跑不起来。
一看就不会做事的人。

鄙视一下
11 楼 shatherm 2009-04-24  
好的,问题都解决了,楼主太谢谢你了! 呵呵
10 楼 ispring 2009-04-21  
shatherm 写道

前面的问题都解决了。。真想和楼主好好谈谈。 现在还有最后的2个问题了,一是 import se.assembla.jce.provider.ms.MSProvider;&nbsp; 包里的MSProvider方法实在是找不到,我照你的提示,加入了bcprov-jdk14-123.jar包&nbsp; ,可是还是不行。不知道是哪个第三方开源包下的。搜索不到。 我和同学商量了下,都不知道是个包下的。 二是虽然创建了类Tool,但是好像类里面少一个方法readRawData("Order.xml");&nbsp;&nbsp; byte[] rawData = Tool.readRawData("Order.xml");&nbsp;&nbsp; 所以这里就无法输出了。。。555555 虽然我已经对您的RSA的代码看的很熟了(这几天开机就看),可是还是想不出这个方法该怎么编写,还是要麻烦你一下。。。希望如果你不忙的话浪费一点时间帮帮我哈! 万分感谢!


前面的注释不是都写了吗:
/** 
* RSA加密算法的使用 
* @author Ivan 
* @DataTime 2006-12-12 16:38 
* Java 本身不提供 RSA 算法的支持 
* 需下载 assembla_msks_jce.jar 或 bcprov-jdk14-123.jar 包 
*/
所以需要去下载一个 assembla_msks_jce.jar 包,至于 readRawData 就是最简单的将文本读入到一个 byte 数组中,并没有别的操作,这个如果不会可以去网上找一下,很多的
9 楼 shatherm 2009-04-17  
前面的问题都解决了。。真想和楼主好好谈谈。
现在还有最后的2个问题了,一是
import se.assembla.jce.provider.ms.MSProvider; 

包里的MSProvider方法实在是找不到,我照你的提示,加入了bcprov-jdk14-123.jar包  ,可是还是不行。不知道是哪个第三方开源包下的。搜索不到。
我和同学商量了下,都不知道是个包下的。

二是虽然创建了类Tool,但是好像类里面少一个方法readRawData("Order.xml");  
byte[] rawData = Tool.readRawData("Order.xml");  

所以这里就无法输出了。。。555555
虽然我已经对您的RSA的代码看的很熟了(这几天开机就看),可是还是想不出这个方法该怎么编写,还是要麻烦你一下。。。希望如果你不忙的话浪费一点时间帮帮我哈!

万分感谢!
8 楼 ispring 2009-04-16  
shatherm 写道

哦,不好意思楼主,还要麻烦您一下哈,RSA算法的这个代码里 除了import com.iuxi.security.util.Tool;以外还有 import se.assembla.jce.provider.ms.MSProvider;&nbsp;&nbsp; import sun.misc.BASE64Decoder;&nbsp;&nbsp; import sun.misc.BASE64Encoder; 这三个包无法导入,请问也是自己写的吗? 还是要安装的eclipse插件?能否指点一下。 最近在研究这个,快急死了!谢谢了


这三个不是我写的,是第三方开源包,是关于编码的,因为是很久以前的代码,我现在也没有了,你可以在网上搜一下就能找到,这几个包很常用的.
7 楼 shatherm 2009-04-16  
哦,不好意思楼主,还要麻烦您一下哈,RSA算法的这个代码里
除了import com.iuxi.security.util.Tool;以外还有

import se.assembla.jce.provider.ms.MSProvider;  
import sun.misc.BASE64Decoder;  
import sun.misc.BASE64Encoder;

这三个包无法导入,请问也是自己写的吗? 还是要安装的eclipse插件?能否指点一下。
最近在研究这个,快急死了!谢谢了
6 楼 ispring 2009-04-15  
原来的那份代码找不到了,我另写了一份
shatherm 写道

楼主,我想请教你一下哈 import com.iuxi.security.util.Tool;能不能贴出来啊? 现在有个输出 System.out.println(Tool.byte2hex(signedData));&nbsp; 这里就要这个类的支持。。。 最近在做一个数字签名模块,好头疼。。。现在想看看这个跑下来的代码。。 拜托楼主了!


原来的那份代码找不到了,我另写了一份:
public static String bytes2hex(byte[] bytes) {
	int length = bytes.length;
	char[] out = new char[length << 1];
	for (int i = 0, j = 0; i < length; i++) {
		out[j++] = DIGITS[(0xF0 & bytes[i]) >>> 4];	// !!!!! 优先级 & 小于 >>>
		out[j++] = DIGITS[0x0F & bytes[i]];
	}
	return new String(out);
}
5 楼 ispring 2009-04-15  
差点忘了另外一个
public static final char[] DIGITS = {
        '0', '1', '2', '3', '4', '5', '6', '7',
           '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
4 楼 ispring 2009-04-15  
原来的那份代码找不到了,我另写了一份
public static String binary2hex2(byte[] bytes) {
	int length = bytes.length;
	char[] out = new char[length << 1];
	for (int i = 0, j = 0; i < length; i++) {
		out[j++] = DIGITS[(0xF0 & bytes[i]) >>> 4];	// !!!!! 优先级 & 小于 >>>
		out[j++] = DIGITS[0x0F & bytes[i]];
	}
	return new String(out);
}
3 楼 shatherm 2009-04-15  
楼主,我想请教你一下哈

import com.iuxi.security.util.Tool;能不能贴出来啊?

现在有个输出 System.out.println(Tool.byte2hex(signedData)); 
这里就要这个类的支持。。。
最近在做一个数字签名模块,好头疼。。。现在想看看这个跑下来的代码。。

拜托楼主了!
2 楼 ispring 2009-03-18  
tanran496 写道

你好,请问import com.iuxi.security.util.Tool; 导入的这个类是在哪个包中?还是自己写的,谢谢!


这个类是我自己写的(而且是很早以前写的),里面都是一些很简单的小功能,比较读取文件内容到byte数组中去,将byte数据以十六进制字符串的形式打印出来等等,如果需要我可以帖出来看看。
1 楼 tanran496 2009-03-18  
你好,请问import com.iuxi.security.util.Tool; 导入的这个类是在哪个包中?还是自己写的,谢谢!

相关推荐

    RSA非对称加密算法

    RSA 非对称加密算法 RSA 非对称加密算法是一种经典的非对称加密算法,由罗纳德·李维斯特、阿迪·萨莫尔和伦纳德·阿德曼三人于 1977 年共同提出的。该算法的主要思想是基于大素数的乘积和因式分解之间的关系,通过...

    RSA.rar_RSA加密文件_RSA加密解密和_rsa加密算法_对称 加密文件_对称加密

    5. **对称加密与非对称加密**:对称加密使用同一密钥进行加密和解密,如DES、AES等,效率高但密钥管理困难。非对称加密如RSA则使用一对公钥和私钥,公钥可以公开,私钥需保密,解决了密钥分发问题,但计算复杂度相对...

    密码学实验_对称加密算法DES_非对称加密算法RSA.pdf

    本实验报告主要涉及两种加密算法:对称加密算法DES(Data Encryption Standard)和非对称加密算法RSA。实验旨在帮助学生深入理解这两种算法的基本原理,并通过Python编程实现加密和解密过程。 ### **对称加密算法...

    RSA加密算法的C语言实现

    RSA加密算法是公钥密码学领域的一个里程碑,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因此得名RSA。它是一种非对称加密算法,即加密和解密使用不同的密钥,极大地提高了安全性。在C语言中实现RSA...

    rsa加密算法的实现

    RSA加密算法是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因其三位发明者的名字首字母命名。它在信息安全领域有着广泛的应用,如数字签名、数据加密以及网络安全传输等。在C语言...

    文件内容加密工具(非对称RSA加密算法版)

    本文将详细介绍一种非对称加密算法——RSA,以及如何使用它来加密文件内容。 RSA是一种广泛使用的公开密钥加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman于1977年提出,因此得名RSA。它的核心原理基于大数...

    C#中关于RSA加密算法(案例代码) c#经典案例.pdf

    在实际应用中,RSA加密算法通常是与其他加密算法结合使用的,如对称加密算法AES等,以提高加密强度和效率。 此外,RSA加密算法也可以用于数字签名和身份验证等领域。 RSA加密算法是一种安全、可靠的加密算法,广泛...

    非对称加密算法流程图

    非对称加密算法流程图,使用visio绘制。

    RSA加密算法源码

    RSA加密算法是公钥密码学中的一个重要里程碑,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年共同提出,因此得名RSA。它是一种非对称加密技术,广泛应用于网络安全、数据加密、数字签名等领域。在本资源中,你...

    C#实现RSA加密算法

    标题提到的"C#实现RSA加密算法"着重讲述了如何在C#中利用大整数类BigInteger和RSACryptoServiceProvider类来完成私钥加密公钥解密的过程。以下是对这个话题的详细解释: 1. **RSA算法基础**: RSA算法由Rivest、...

    C++实现RSA加密算法

    RSA加密算法是一种非对称加密技术,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因此得名RSA。它是现代密码学的基础之一,广泛应用于网络安全,如数据传输加密、数字签名等场景。在这个案例中,我们将...

    RSA非对称加密解密Delphi源码

    RSA是一种非对称加密算法,由Ron Rivest、Adi ...通过学习和理解这段Delphi RSA源码,开发者不仅可以掌握RSA加密技术,还可以深入了解非对称加密算法的实现细节,同时提高在Delphi环境下编写安全、高效代码的能力。

    PB12.5可实用的RSA加密算法(源码含Demo).zip

    RSA加密算法是一种非对称加密技术,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,是现代密码学的基石之一。在PowerBuilder(PB)开发环境中,使用RSA算法可以实现数据的安全传输和存储。PB12.5是Power...

    RSA加密算法流程图源代码

    RSA加密算法是公钥密码学领域的一个里程碑,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因此得名RSA。它是一种非对称加密算法,即加密和解密使用不同的密钥,极大地提高了安全性。在网络安全、数据...

    Rsa.rar_RSA 算法_java 非对称 加密 算法_rsa java

    RSA算法是一种非对称加密算法,它在信息安全领域有着广泛的应用,特别是在数据传输中的安全保护。这个RAR压缩包包含了一个名为“Rsa.java”的源代码文件,可能是用于演示如何在Java环境中实现RSA算法。另一个文件...

    java rsa加密算法实现

    RSA是一种非对称加密算法,它是...以上就是关于"java rsa加密算法实现"的相关知识点,希望对你理解Java中的RSA加密有所帮助。在实际编程中,根据具体需求选择合适的加密策略,并确保遵循最佳实践,以保证系统的安全性。

    RSA加密算法在VB中的实现.rar_RSA VB_VB RSA_rsa加密算法_vb rsa_vb 加密

    在"RSA加密算法在VB中的实现.txt"文件中,可能包含以下步骤的实现细节: 1. 素数检测:通过Primality Test(如Miller-Rabin测试)判断给定的数字是否为素数。 2. 欧拉函数计算:根据p和q计算φ(N)。 3. 模逆计算:...

    非对称加密算法 数字签名算法

    同时,文件中的`非对称加密算法 数字签名算法——RSA - 信息安全 - ITeye知识库频道_files`可能包含更多示例代码和详细解释,有助于进一步学习和实践。 总之,非对称加密算法和数字签名是保障网络通信安全的重要...

    RSA加密算法实现

    RSA加密算法是现代密码学中的一个关键组成部分,它在数据安全、网络安全以及数字签名等领域有着广泛的应用。这个算法由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因此得名RSA。RSA是一种非对称加密算法...

Global site tag (gtag.js) - Google Analytics