非对称加密 RSA算法

RSA

也是公开密钥密码,非对称密码
要破解面临两大问题

  • 大整数分解(integer factorization)——由2个质数p,q相乘得到大整数n容易,由n分解为2个质数难(耗时)
  • 离散对数(discrete logarithm)——m的e次方模上n得到c容易;已知c,n,e得到m难

上面的情况都是针对较大的数

原理

RSA

java实现

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Scanner;

public class RSA_scanner {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        HashMap<String, Object> map = getKeys();
        RSAPublicKey publicKey = (RSAPublicKey) map.get("public");//公钥
        RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");//私钥
        String plaintext = new String(); //明文
        String ciphertest = new String(); //密文

        while(scanner.hasNext()) {
            if("-e".equals(scanner.nextLine())){
                //读取明文
                plaintext = ReadText2String(new File("src/test2/plaintext.txt"));
                System.out.println("读入的明文是:\n" + plaintext);
                try {
                    ciphertest = encryptByPublicKey(plaintext, publicKey);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //将密文写入文件
                WriteText2String(ciphertest, new File("src/test2/ciphertext.txt")); 
                System.out.println("加密后的密文是:\n" + ciphertest);
            }

            if("-d".equals(scanner.nextLine())){
                //读取密文
                ciphertest = ReadText2String(new File("src/test2/ciphertext.txt"));
                System.out.println("读入的密文是:\n" + ciphertest);
                try {
                    plaintext = decryptByPrivateKey(ciphertest, privateKey);
                } catch (Exception e) {
                    e.printStackTrace();
                } //解密
                //将明文写入文件
                WriteText2String(plaintext, new File("src/test2/plaintext.txt")); 
                System.out.println("解密后的明文是:\n" + plaintext);
            }
        }

    }

    /**
     * 生成公钥和私钥
     */
    public static HashMap<String, Object> getKeys(){
        HashMap<String, Object> map = new HashMap<String, Object>();
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024);
            KeyPair keypair = keyPairGenerator.generateKeyPair();
            //得到公钥
            RSAPublicKey publicKey = (RSAPublicKey)keypair.getPublic();
            //得到私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keypair.getPrivate();
            //放入到map中
            map.put("public", publicKey);
            map.put("private", privateKey);
            return map;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    /**
     * 公钥加密
     */
    public static String encryptByPublicKey(String data, RSAPublicKey publicKey) throws Exception{
        //根据公钥拿到参数n,e
        BigInteger n = publicKey.getModulus();
        BigInteger e = publicKey.getPublicExponent();
        //将明文转化为字节
        byte plain_byte[] = data.getBytes("utf-8");
        BigInteger m = new BigInteger(plain_byte);
        //计算密文
        BigInteger c = m.modPow(e, n);
        return c.toString();
    }

    /**
     * 私钥解密
     */
    public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception{
        //获取参数n, d
        BigInteger n = privateKey.getModulus();
        BigInteger d = privateKey.getPrivateExponent();
        //将密文转化为大整数
        //byte[] cipher_byte = data.getBytes("utf-8");
        BigInteger c = new BigInteger(data);
        //解密
        BigInteger m = c.modPow(d, n);
        return new String(m.toByteArray(), "utf-8");
    }

    /**
     * 写文件
     */
    public static void WriteText2String(String output, File file) {
        try {
            FileOutputStream fout = new FileOutputStream(file);
            OutputStreamWriter out = new OutputStreamWriter(fout, "utf-8");
            out.write(output);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 读文件
     */
    public static String ReadText2String(File file){
        StringBuilder result = new StringBuilder();
        try{
            FileInputStream fin = new FileInputStream(file);
            InputStreamReader input = new InputStreamReader(fin, "utf-8");
            int content = 0;
            while((content = input.read())!=-1){
                result.append((char)content);
            }
            input.close();
        }catch(Exception e){
            e.printStackTrace();
        }
        return result.toString();
    }

}

测试

eclipse下的测试结果
这里写图片描述

参考:http://blog.csdn.net/houzuoxin/article/details/39054895

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值