RSA笔记

学习:http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html

1:n = 61X53 = 3233   3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位

2:φ(n) = (p-1)(q-1) = 60X52 = 3120(φ(n)欧拉函数)

3:e = 17;  随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。实际应用中,常常选择65537

4:d = 2753 ,e对于φ(n)的模反元素,即:ed+1=φ(n)

将n和e封装成公钥,n和d封装成私钥,即:

 模:n

公钥指数:e

私钥指数:d (要想破解d,得知道φ(n),得知道p,q,当n足够大时,有难度)

 

加密:m为被加密的值(必须<n),c为加密之后的值

me ≡ c (mod n)

cd ≡ m (mod n)

 

公钥(n,e) 只能加密小于n的整数m,那么如果要加密大于n的整数,该怎么办?有两种解决方法:一种是把长信息分割成若干段短消息,每段分别加密;另一种是先选择一种"对称性加密算法"(比如DES),用这种算法的密钥加密信息,再用RSA公钥加密DES密钥

 

从公钥解析出e和n:

参考:https://www.jianshu.com/p/46713d073cc6

3082010A0282010100A45DC4D1503AF9AA29D6A61732CE11899A9B7FE825B8121D86D1329AC93D2A86BF7EEF12CD0EBF0E9716287945F99DBF4494A8A5B1A8A040BC48140687C673C72CD7186CAB5637CB03F3A4917B084F4AAAE9050B18A1D411975DB6707A61B10FA7EB96F30ABE66B272F1690D9DC78504A5D9EAC4275D2810EA58FC72EB35D7321EAEDF6D25D712495C8781682E6C6C193658D79F28A8BCDAC99C2CDED2FF2E9FF88D9C321162B7CC2047CB81AF1E71B724B02FB8419B239CB4755E6255493CA9F045B872F8C85F73A30DC4A47283847D27854F2B0DA365FC35B6C111DBE08713CDB20213D6C50D003B043FC1A8DFB341F2BF731FD95926CD13C7192CA7862C2F0203010001

3082010A0282010100A45DC4D1503AF9AA29D6A61732CE11899A9B7FE825B8121D86D1329AC93D2A86BF7EEF12CD0EBF0E9716287945F99DBF4494A8A5B1A8A040BC48140687C673C72CD7186CAB5637CB03F3A4917B084F4AAAE9050B18A1D411975DB6707A61B10FA7EB96F30ABE66B272F1690D9DC78504A5D9EAC4275D2810EA58FC72EB35D7321EAEDF6D25D712495C8781682E6C6C193658D79F28A8BCDAC99C2CDED2FF2E9FF88D9C321162B7CC2047CB81AF1E71B724B02FB8419B239CB4755E6255493CA9F045B872F8C85F73A30DC4A47283847D27854F2B0DA365FC35B6C111DBE08713CDB20213D6C50D003B043FC1A8DFB341F2BF731FD95926CD13C7192CA7862C2F0203010001

结构头:

3082010A

30 :Type
010A(以下内容总长度:266): 下面内容总长度,超过了0xFF,所以用两个字节描述,所以第二个字节为82,如果下面总长度没有超过0xFF,只用一个字节可以描述,则为81

02820101

02子结构的类型

82:代表内容的长度需要用两个字节表示

0101:长度257

00A45D......:模,以00开头代表大于0

RSA公钥N的第一个字节如果大于0x80,则需要在公钥值前面补00,这是因为modulus 为一个大整数,最高位为符号位,其为1时,就是负数,所以要在最高位填充0x00以保证不为负。

代码:

public static void getPublicKeyElements(byte[] stream) {
        List<BerTlv> berTlvs = new BerTlvParser().parse(stream).getList();
        List<BerTlv> tlvs = berTlvs.get(0).findAll(new BerTag(0x02));
        final byte[] modulus = tlvs.get(0).getBytesValue();
        final byte[] exp = tlvs.get(1).getBytesValue();
        return pubkeyElements;
    }

 得出以上公钥解析出e和moduls:
e:010001

modulus--->A45DC4D1503AF9AA29D6A61732CE11899A9B7FE825B8121D86D1329AC93D2A86BF7EEF12CD0EBF0E9716287945F99DBF4494A8A5B1A8A040BC48140687C673C72CD7186CAB5637CB03F3A4917B084F4AAAE9050B18A1D411975DB6707A61B10FA7EB96F30ABE66B272F1690D9DC78504A5D9EAC4275D2810EA58FC72EB35D7321EAEDF6D25D712495C8781682E6C6C193658D79F28A8BCDAC99C2CDED2FF2E9FF88D9C321162B7CC2047CB81AF1E71B724B02FB8419B239CB4755E6255493CA9F045B872F8C85F73A30DC4A47283847D27854F2B0DA365FC35B6C111DBE08713CDB20213D6C50D003B043FC1A8DFB341F2BF731FD95926CD13C7192CA7862C2F

 

posted @ 2020-06-26 09:16  蜗牛攀爬  阅读(205)  评论(0编辑  收藏  举报