数据结构与算法

加密算法(二,RSA算法)

2019-04-16  本文已影响0人  腊鸡程序员
timg (4).jpg
简介

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美国公布,当时他们三人都在麻省理工学院工作实习。RSA就是他们三人姓氏开头字母拼在一起组成的。

RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。

今天只有短的RSA钥匙才可能被强力方式解破。
到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。
只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战和质疑。

算法思想
  1. 问题提出
    1970年以前,密码学一直使用对称密钥,
    如果一个人需要和多个人分享信息,比如银行需要存放所有人的密码,来进行信息交换,必然需要管理所有的密钥.
    能否有一种更简单的方法呢?

1970年一个英国工程师和数学家James H.Ellis 在研究一个非秘密的加密想法,基于一个简单又聪明的想法,上锁和解锁是相反的操作
他可以把锁打开,交给对方后,由对方上好锁,再还给他,由他自己开锁
这样他可以大量发出他的信息,而只需要保留单个钥匙
当然他给出了工作原理,但不知如何用数学方法解决

image.png
  1. 解决

被另一个数学家和密码专家Cocks发现
他需要一个特殊的单向函数,正推容易,求逆很难

image.png

求素数的因子分解589=19*31,计算很难,如果是个1000位数呢?

欧拉发现了一个重要的函数phi(n),用于找到整数的可分解性

image.png
image.png image.png image.png image.png image.png

RSA算法推论:


image.png image.png

实现:

image.png
代码:
import org.junit.Test;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;

public class RSA {

    public static String ALGORITHM = "RSA";

    //指定key的位数 N的位数
    public static int keySize = 1024;

    //指定公钥的存放文件
    public static String PUBLIC_KEY_FILE = "public_key.dat";

    //指定私钥的存放文件
    public static String PRIVATE_KEY_FILE = "private_key.dat";

    /**
     * 生成秘钥对 公钥(e,n) 私钥(d,n)
     */
    public static void generateKeyPair() throws  Exception{
        SecureRandom sr = new SecureRandom();
        //初始化KeyPairGenerator对象
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(keySize,sr);
        //生成秘钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        //得到公钥
        Key publicKey = keyPair.getPublic();
        //得到私钥
        Key privateKey = keyPair.getPrivate();

        //可以写入文件后,这两个文件分别放在客户端和服务器
        ObjectOutputStream outputStream1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
        ObjectOutputStream outputStream2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
        outputStream1.writeObject(publicKey);
        outputStream2.writeObject(privateKey);
        outputStream1.close();
        outputStream2.close();
    }

    /**
     * 加密
     * @param source 明文
     * @return
     * @throws Exception
     */
    public static String encrypt(String source) throws Exception{
        generateKeyPair();
        //取出公钥
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
        Key key = (Key) ois.readObject();
        ois.close();
        //开始使用公钥
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE,key);
        byte[] b = source.getBytes();
        byte[] b1 = cipher.doFinal(b);
        //用BASE64编码,二进制和字符串的转化的一种方式
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b1);
    }

    /**
     * 解密
     * @param cryptText 密文
     * @return
     */
    public static String decrypt(String cryptText) throws Exception{
        //读文件,获取私钥
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
        Key key = (Key) ois.readObject();
        ois.close();
        //解密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE,key);
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b = decoder.decodeBuffer(cryptText);
        byte[] b1 = cipher.doFinal(b);
        return new String(b1);
    }

    @Test
    public void test() throws Exception{
        String source = "jett";
        String encryptText = encrypt(source);
        System.out.println("加密后:" +encryptText);
        String decryptText = decrypt(encryptText);
        System.out.println("解密后:" + decryptText);
    }
}

上一篇 下一篇

猜你喜欢

热点阅读