RSA加密算法Java应用

一.什么是RSA算法

1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。

这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

RSA算法包括RSA加密方案和RSA签名方案。下文主要讨论RSA加密算法。

二.RSA加密算法的执行步骤

1.生成密钥

第一步,随机选择两个不相等的质数p和q。
第二步,计算p和q的乘积n,即n=pq,这里将n表示成二进制的长度就是密钥长度。实际应用中,RSA密钥一般是1024位,重要场合则为2048位。
第三步,计算n的欧拉函数φ(n),φ(n) = (p-1)(q-1)。
第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。
第五步,计算e对于φ(n)的模反元素d。所谓"模反元素"就是指有一个整数d,可以使得ed被φ(n)除的余数为1,即ed ≡ 1 (mod φ(n))
第六步,将n和e封装成公钥,n和d封装成私钥,即pk=(n,e),sk=(n,d)。

2.加密

假设A要向B发送待加密的信息m,A就要用B的公钥 (n,e) 对m进行加密生成密文c,然后将密文c发送给B。这里需要注意,m必须是整数(字符串可以取ascii值或unicode值),且m必须小于n。
所谓"加密",就是算出下式的c :
me ≡ c (mod n)

3.解密

B收到A发送过来的密文c以后,使用自己的私钥(n,d)对c进行解密,就可以得到明文m。
所谓“解密”,就是算出下式的m:
cd ≡ m (mod n)

三.RSA加密算法的原理

RSA算法原理(一)
RSA算法原理(二)

四.RSA加密算法Java应用

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.security.*;

public class RSAEncrypt {
    //指定加密算法为RSA
    private static final String ALGORITHM = "RSA";
    //指定密钥长度
    private static final int KEY_SIZE = 1024;
    //指定私钥存放文件
    private static final String PRIVATE_KEY_FILE = "PrivateKey";
    //指定公钥存放文件
    private static final String PUBLIC_KEY_FILE = "PublicKey";

    /**
     * 生成密钥
     */
    private void generateKey() {
        try {
            //指定随机数源
            SecureRandom secureRandom = new SecureRandom();
            //为RSA算法创建一个KeyPairGenerator对象
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
            //初始化KeyPairGenerator对象
            keyPairGenerator.initialize(KEY_SIZE, secureRandom);
            //生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            //获取私钥
            Key privateKey = keyPair.getPrivate();
            //获取公钥
            Key publicKey = keyPair.getPublic();
            //将私钥和公钥写入文件
            ObjectOutputStream privateKeyStream = new ObjectOutputStream(
                    new FileOutputStream(PRIVATE_KEY_FILE));
            ObjectOutputStream publicKeyStream = new ObjectOutputStream(
                    new FileOutputStream(PUBLIC_KEY_FILE));
            privateKeyStream.writeObject(privateKey);
            publicKeyStream.writeObject(publicKey);
            privateKeyStream.close();
            publicKeyStream.close();
        } catch (NoSuchAlgorithmException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 加密算法
     * @param plaintext  明文
     * @return  密文
     */
    public String encrypt(String plaintext){
        try {
            //读取文件获取公钥
            ObjectInputStream inputStream = new ObjectInputStream(
                    new FileInputStream(PUBLIC_KEY_FILE));
            Key publicKey = (Key) inputStream.readObject();
            inputStream.close();
            //得到Cipher对象来实现RSA加密算法
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] bytes = cipher.doFinal(plaintext.getBytes());
            BASE64Encoder base64Encoder = new BASE64Encoder();
            return base64Encoder.encode(bytes);
        } catch (IOException | ClassNotFoundException | NoSuchPaddingException
                | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密算法
     * @param ciphertext  密文
     * @return  明文
     */
    public String decrypt(String ciphertext){
        try {
            //读取文件获取私钥
            ObjectInputStream inputStream = new ObjectInputStream(
                    new FileInputStream(PRIVATE_KEY_FILE));
            Key privateKey = (Key) inputStream.readObject();
            inputStream.close();
            //得到Cipher对象来实现RSA解密算法
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            BASE64Decoder base64Decoder = new BASE64Decoder();
            byte[] bytes = base64Decoder.decodeBuffer(ciphertext);
            return new String(cipher.doFinal(bytes));
        } catch (IOException | ClassNotFoundException | NoSuchPaddingException
                | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        RSAEncrypt rsaEncrypt = new RSAEncrypt();
        rsaEncrypt.generateKey();
        String message = "Hello World";
        String ciphertext = rsaEncrypt.encrypt(message);
        System.out.println("ciphertext: " + ciphertext);

        String plaintext = rsaEncrypt.decrypt(ciphertext);
        System.out.println("plaintext: " + plaintext);
    }
}

打印结果为:

ciphertext: R6rW79OHQQvEBtchRETqQuNVKZ5ePV3K3XSknqYX1b1MqEGPTE3aZaHFAc98jsvLf3wLOAXKvGxT
VFUcTNom5W01mz9U8BhU6g3I07ZJWwYJDKrMuoaE26RlkWILa2f2lGDVUJ+2xB75EqZzq8bAxlEn
oqv8d+vaaoWGJ8PIpAQ=
plaintext: Hello World

参考:
RSA加密算法Java应用实例

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容

  • 姓名:于川皓 学号:16140210089 转载自:https://baike.baidu.com/item/RS...
    道无涯_cc76阅读 2,543评论 0 1
  • 前言 本文的RSA例子代码更新在我的github上。 RSA算法是最重要算法之一,它是计算机通信安全的基石,保证了...
    game3108阅读 11,657评论 2 53
  • Base64 base64是一种基于64个可打印字符来表示二进制数据的表示方法.严格来说它只能算作一种编码方式.B...
    miku酱啦阅读 1,190评论 0 3
  • 这是去年12月在CSDN写的一篇加密算法文章 现在决定在简书写博客 移植过来方便复习再理解。 最近算法课老师要求小...
    icecrea阅读 1,294评论 1 1
  • 一年级上(中) 二年级上(中)
    破茧成蝶我最棒阅读 125评论 0 1