RSA的一些资料

阅读更多

RSA

Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1

 

目录

1介绍3

2标记法3

3密钥类型4

3.1RSA公钥4

3.2RSA私钥5

4数据转换原语6

4.1I2OSP6

4.2OS2IP7

5密码原语7

5.1加密解密原语7

5.1.1RSAEP7

5.1.2RSADP7

5.2签名和验证原语8

6方案概要8

7加密方案8

7.1RSAES-OAEP8

7.2RSAES-PKCS1-v1_58

8签名方案-附8

8.1RSASSA-PSS8

8.2RSASSA-PKCS1-v1_58

9签名的编码方式-附9

9.1EMSA-PSS9

9.2EMSA-PKCS1-v1_59

10Openssl9

10.1DER9

10.2PEM9

10.2.1例子:PEM格式内容9

10.3rsa_public_key.pem10

10.3.1PEM文件解析11

附录 A ASN.1语法19

A.1 RSA 密钥描述19

A.1.1 RSA 公钥语法19

A.1.2 RSA 私钥语法19

A.2 体系验证20

 

1介绍

文档提供了基于RSA算法的公钥密码体系的实现提议,包括以下几个方面:

*加密原语

*加密方案

*签名方案-附

*

 

在RSA wiki(https://en.wikipedia.org/wiki/RSA)上看到有如下描述:

RSA (cryptosystem), the Rivest-Shamir-Adleman cryptosystem, a cryptosystem for public-key encryption

从以上描述中可以看出RSA是一种公钥加密的密码系统。RSA也叫Rivest-Shamir-Adleman cryptosystem,由Ron Rivest, Adi Shamir和Leonard Adleman于MIT提出。RSA名称也是由Ron Rivest, Adi Shamir和Leonard Adleman三人名字中的首字母而来。

 

2标记法

 

3密钥类型

本文档中定义的原语和方案中使用了两种密钥类型:RSA公钥和RSA私钥。同时,RSA公钥和RSA私钥组成一个RSA密钥对。

该规范支持所谓的“多素数”("multi-prime")RSA,模数(modulus)可能有两个以上的素因子(prime factor)。

 

3.1RSA公钥

RSA公钥由两个组件组成:

n RSA模数,一个正整数

e RSA公开(public)指数,一个正整数

一个有效的RSA公钥,RSA模数n为u个不同的奇素数(r_i,i = 1, 2, ..., u,u>=2, 如r_1, r_2, r_3, r_4, r_5,…,r_u。)的乘积。RSA公开(public)指数e是一个3到n-1之间的正整数,满足:

GCD(e,\lambda(n)) = 1

 

其中\lambda(n)=LCM(r_1 - 1, ..., r_u - 1),例如一组奇素数r_1, r_2, r_3, r_4, r_5,r_6, r_7为2、3、5、7、11、13、17,那么\lambda(n)为1,2,4,6,10,12,16的公倍数。

 

按照惯例,开始的两个素数r_1和r_2也可能分别由p和q指定。

 

素数又称质数(prime number),有无限个。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数

质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数。

如2、3、5、7、11、13、17都是些素数

 

GCD(greatest common divisor),最大公约数。

LCM(least common multiple),最小公倍数。

 

3.2RSA私钥

一个RSA私钥可能有两种表示。

第一种表示由(n, d)对组成

n     RSA模数,一个正整数

d    RSA私有指数,一个正整数

第二种表示由一个5元组(p, q, dP, dQ, qInv)和一序列(可能为空)3元组(r_i, d_i, t_i)

组成。i = 3, ..., u,其中的每一个素数不会在5元组中出现。

 

p   首因子,一个正整数

q   次因子,一个正整数

dP  首因子的CRT指数,一个正整数

dQ  次因子的CRT指数,一个正整数

qInv  CRT系数(第一个),一个正整数

r_i   因子(第i个),一个正整数

d_i   因子(第i个)的CRT指数,一个正整数

t_i  因子(第i个)的CRT系数,一个正整数

对于第一种表示,一个有效的RSA私钥,RSA中的模数n和对应RSA公钥中的模数是相同的,并且模数n为u个不同的奇素数(r_i,i = 1, 2, ..., u,u>=2, 如r_1, r_2, r_3, r_4, r_5,…,r_u。)的乘积。RSA私有指数d是一个小于n的正整数,满足:

 

e * d == 1 (mod \lambda(n))

 

其中e是RSA公钥中的公开(public)指数,\lambda(n)的定义也和RSA公钥中定义的一样。

 

对于第二种表示,一个有效的RSA私钥,p和q这两个因子就是RSA模数n的开始两个素数因子(例如,r_1和r_2),CRT指数dP和dQ是一个分别小于p和q的正整数,满足:

e * dP == 1 (mod (p-1))

e * dQ == 1 (mod (q-1))

 

CRT系数qInv是一个小于p的正整数,满足:

q * qInv == 1 (mod p)

 

如果u>2, 这种表示将包含一个或多个3元组(r_i, d_i, t_i),i=3, ..., u。因子r_i就是RSA模数n额外的素数因子。每一个CRT指数d_i (i = 3, ..., u)满足:

e * d_i == 1 (mod (r_i - 1))

 

每一个CRT系数t_i (i = 3, ..., u)是一个小于r_i的正整数,满足:

R_i * t_i == 1 (mod r_i)

其中R_i = r_1 * r_2 * ... * r_(i-1)

 

 

 

4数据转换原语

文档中定义的体系使用了两种数据转换原语。

I2OSP:Integer-to-Octet-String原语

OS2IP: Octet-String-to-Integer原语

4.1I2OSP

I2OSP转换非负整数为一个指定长度的8位位组字符串(octet string)。

 

I2OSP (x, xLen)

 

输入:

x        将被转换的非负整数

xLen     返回的8位位组字符串(octet string)的长度。

 

输出:

X        对应的8位位组字符串(octet string),长度为xLen

 

错误: “传入的非负整数太大”

 

 

 

 

4.2OS2IP

 

5密码原语

 

5.1加密解密原语

加密原语输入一个表示明文的整数,在指定公钥下加密输出一个表示密文的整数,解密原语是加密原语的逆过程,输入表示密文的整数,在指定对应的私钥下输出恢复原来的表示明文的整数。

文档中定义加密体系使用了一对加密解密原语:

RSAEP/RSADP

RSAEP和RSADP围绕相同的数学操作,只是输入的密钥不同,RSAEP输入的是公钥,RSADP输入的是私钥。

这里定义的原语和IEEE标准 1363-2000 [26]中IFEP-RSA/IFDP-RSA是一致的(除非新增了RSA多素数的支持),同时兼容PKCS #1 v1.5

 

这两个原语主要的数学操作就是求幂。

 

5.1.1RSAEP

 

RSAEP(RSA Encryption primitives), RSA加密原语

 

RSAEP((n, e), m)

 

输入:

(n, e)  RSA公钥

m       信息描述,一个整数(0到n-1)

 

输出:

c       密文描述,一个整数(0到n-1)

 

错误:“信息描述超过了范围”

 

假定:RSA公钥(n, e)有效

 

步骤:

1、如果信息描述m不在0到n-1之间,输出“信息描述超过了范围”并退出。

2、对c作如下运算:c = m^e mod n

3、输出c。

 

5.1.2RSADP

RSADP(RSA Decryption primitives), RSA解密原语

RSADP (K, c)

输入:

K        RSA私钥,其中K可以是以下形式中的一个:

         - (n, d)对

         -一个5元组(p, q, dP, dQ, qInv)和一序列(可能为空)3元组(r_i, d_i, t_i), i = 3, ..., u

c        一个表示密文的整数,该整数在0到n-1之间。

 

输出:

m        一个表示明文的整数,该整数在0到n-1之间。

错误:“表示密文的整数超过了范围”

 

假定:RSA私钥K有效

 

步骤:

1、如果表示密文的整数c不在0到n-1之间,输出“表示密文的整数超过了范围”并退出。

2、对表示明文的整数m作如下运算:

a.如果K使用的是第一种形式:(n, d)对,对m作如下运算:m = c^d mod n

b.如果K使用的是第二种形式:一个5元组(p, q, dP, dQ, qInv)和一序列(可能为空)3元组(r_i, d_i, t_i), i = 3, ..., u,处理如下:

i.赋值m_1 = c^dP mod p,以及m_2 = c^dQ mod q

ii.如果u>2,赋值m_i = c^(d_i) mod r_i, i = 3, ..., u

iii.赋值h = (m_1 - m_2) * qInv mod p

iv.赋值m = m_2 + q * h

v.如果u>2,赋值R = r_1,并且遍历i=3到u,执行:

1.赋值R = R * r_(i-1)

2.赋值h = (m_i - m) * t_i mod r_i

3.赋值m = m + R * h

3、输出m

5.2签名和验证原语

 

6方案概要

 

7加密方案

 

7.1RSAES-OAEP

 

7.2RSAES-PKCS1-v1_5

 

8签名方案-附

 

8.1RSASSA-PSS

 

8.2RSASSA-PKCS1-v1_5

 

9签名的编码方式-附

 

9.1EMSA-PSS

 

9.2EMSA-PKCS1-v1_5

 

10Openssl

 

10.1DER

 

二进制DER编码

10.2PEM

 

PEM stands for Privacy Enhanced Mail. PEM文件采用的是ASCII(Base64)编码,PEM文件使用Base64进行编码。

 

10.2.1例子:PEM格式内容

-----BEGIN PRIVACY-ENHANCED MESSAGE-----

Proc-Type: 4,ENCRYPTED

Content-Domain: RFC822

DEK-Info: DES-CBC,F8143EDE5960C597

Originator-ID-Symmetric: [email protected],,

Recipient-ID-Symmetric: [email protected],ptf-kmc,3

Key-Info: DES-ECB,RSA-MD2,9FD3AAD2F2691B9A,

          B70665BB9BF7CBCDA60195DB94F727D3

Recipient-ID-Symmetric: [email protected],ptf-kmc,4

Key-Info: DES-ECB,RSA-MD2,161A3F75DC82EF26,

          E2EF532C65CBCFF79F83A2658132DB47

 

LLrHB0eJzyhP+/fSStdW8okeEnv47jxe7SJ/iN72ohNcUk2jHEUSoH1nvNSIWL9M

8tEjmF/zxB+bATMtPjCUWbz8Lr9wloXIkjHUlBLpvXR0UrUzYbkNpk0agV2IzUpk

J6UiRRGcDSvzrsoK+oNvqu6z7Xs5Xfz5rDqUcMlK1Z6720dcBWGGsDLpTpSCnpot

dXd/H5LMDWnonNvPCwQUHt==

-----END PRIVACY-ENHANCED MESSAGE-----

 

 

 

 

genrsa -out rsa_key.pem 1024

 

rsa -in rsa_key.pem -noout -text

 

genrsa -des -out rsa_key_endes.pem 1024

 

genrsa -des3 -out rsa_key_endes3.pem 1024

 

genrsa -aes128 -out rsa_key_enaes128.pem 1024

 

 

pkcs8 -topk8 -inform PEM -in rsa_key.pem -outform PEM -nocrypt -out key.pem

 

 

rsa -in rsa_key.pem -pubout -out rsa_public_key.pem

 

10.3rsa_public_key.pem

假设生成的RSA公钥(rsa_public_key.pem文件)内容如下:

 

-----BEGIN PUBLIC KEY-----

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDW/XkRFZ+FtYB3bfHYnRoLyRIm

ch4+6ymFh3K8O9Cbb0HZg64MLi3lnyW3zoqMWjUI5aszCoZ2duqNy/BSBFtmuBGn

OK6i6QWmPZu+c8NpfVbWe5GxWXg/yeaYv5GlpA2hBlnDw3UDUdl6pyZyUH+PAN5i

yQwAq7JjDh8p9V4G9QIDAQAB

-----END PUBLIC KEY-----

 

10.3.1PEM文件解析

 

typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);

 

struct crypto_ex_data_st

{

STACK_OF(void) *sk;

int dummy; /* gcc is screwing up this data structure :-( */

};

 

typedef struct crypto_ex_data_st CRYPTO_EX_DATA;

 

 

struct bio_st

{

BIO_METHOD *method;

/* bio, mode, argp, argi, argl, ret */

long (*callback)(struct bio_st *,int,const char *,int, long,long);

char *cb_arg; /* first argument for the callback */

 

int init;

int shutdown;

int flags;/* extra storage */

int retry_reason;

int num;

void *ptr;

struct bio_st *next_bio;/* used by filter BIOs */

struct bio_st *prev_bio;/* used by filter BIOs */

int references;

unsigned long num_read;

unsigned long num_write;

 

CRYPTO_EX_DATA ex_data;

};

 

 

typedef struct bio_st BIO;

 

 

typedef struct bio_method_st

{

int type;

const char *name;

int (*bwrite)(BIO *, const char *, int);

int (*bread)(BIO *, char *, int);

int (*bputs)(BIO *, const char *);

int (*bgets)(BIO *, char *, int);

long (*ctrl)(BIO *, int, long, void *);

int (*create)(BIO *);

int (*destroy)(BIO *);

        long (*callback_ctrl)(BIO *, int, bio_info_cb *);

} BIO_METHOD;

 

static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)

{

int ret=0;

 

buf[0]='\0';

if (bp->flags&BIO_FLAGS_UPLINK)

{

if (!UP_fgets(buf,size,bp->ptr))

goto err;

}

else

{

if (!fgets(buf,size,(FILE *)bp->ptr))

goto err;

}

if (buf[0] != '\0')

ret=strlen(buf);

err:

return(ret);

}

 

 

static BIO_METHOD methods_filep=

{

BIO_TYPE_FILE,

"FILE pointer",

file_write,

file_read,

file_puts,

file_gets,

file_ctrl,

file_new,

file_free,

NULL,

};

 

BIO_METHOD *BIO_s_file(void)

{

return(&methods_filep);

}

 

BIO *BIO_new(BIO_METHOD *method)

{

BIO *ret=NULL;

 

ret=(BIO *)OPENSSL_malloc(sizeof(BIO));

if (ret == NULL)

{

BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);

return(NULL);

}

if (!BIO_set(ret,method))

{

OPENSSL_free(ret);

ret=NULL;

}

return(ret);

}

 

long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)

{

long ret;

long (*cb)(BIO *,int,const char *,int,long,long);

 

if (b == NULL) return(0);

 

if ((b->method == NULL) || (b->method->ctrl == NULL))

{

BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);

return(-2);

}

 

cb=b->callback;

 

if ((cb != NULL) &&

((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))

return(ret);

 

ret=b->method->ctrl(b,cmd,larg,parg);

 

if (cb != NULL)

ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,

larg,ret);

return(ret);

}

 

 

#define BIO_set_fp(b,fp,c)BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)

 

int BIO_gets(BIO *b, char *in, int inl)

{

int i;

long (*cb)(BIO *,int,const char *,int,long,long);

 

if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))

{

BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);

return(-2);

}

 

cb=b->callback;

 

if ((cb != NULL) &&

((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))

return(i);

 

if (!b->init)

{

BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);

return(-2);

}

 

i=b->method->bgets(b,in,inl);

 

if (cb != NULL)

i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,

0L,(long)i);

return(i);

}

 

 

int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,

    long *len)

{

EVP_ENCODE_CTX ctx;

int end=0,i,k,bl=0,hl=0,nohead=0;

char buf[256];

BUF_MEM *nameB;

BUF_MEM *headerB;

BUF_MEM *dataB,*tmpB;

 

nameB=BUF_MEM_new();

headerB=BUF_MEM_new();

dataB=BUF_MEM_new();

if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))

{

BUF_MEM_free(nameB);

BUF_MEM_free(headerB);

BUF_MEM_free(dataB);

PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);

return(0);

}

 

buf[254]='\0';

for (;;)

{

i=BIO_gets(bp,buf,254);

 

if (i <= 0)

{

PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);

goto err;

}

 

while ((i >= 0) && (buf[i] <= ' ')) i--;

buf[++i]='\n'; buf[++i]='\0';

 

if (strncmp(buf,"-----BEGIN ",11) == 0)

{

i=strlen(&(buf[11]));

 

if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)

continue;

if (!BUF_MEM_grow(nameB,i+9))

{

PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);

goto err;

}

memcpy(nameB->data,&(buf[11]),i-6);

nameB->data[i-6]='\0';

break;

}

}

hl=0;

if (!BUF_MEM_grow(headerB,256))

{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }

headerB->data[0]='\0';

for (;;)

{

i=BIO_gets(bp,buf,254);

if (i <= 0) break;

 

while ((i >= 0) && (buf[i] <= ' ')) i--;

buf[++i]='\n'; buf[++i]='\0';

 

if (buf[0] == '\n') break;

if (!BUF_MEM_grow(headerB,hl+i+9))

{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }

if (strncmp(buf,"-----END ",9) == 0)

{

nohead=1;

break;

}

memcpy(&(headerB->data[hl]),buf,i);

headerB->data[hl+i]='\0';

hl+=i;

}

 

bl=0;

if (!BUF_MEM_grow(dataB,1024))

{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }

dataB->data[0]='\0';

if (!nohead)

{

for (;;)

{

i=BIO_gets(bp,buf,254);

if (i <= 0) break;

 

while ((i >= 0) && (buf[i] <= ' ')) i--;

buf[++i]='\n'; buf[++i]='\0';

 

if (i != 65) end=1;

if (strncmp(buf,"-----END ",9) == 0)

break;

if (i > 65) break;

if (!BUF_MEM_grow_clean(dataB,i+bl+9))

{

PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);

goto err;

}

memcpy(&(dataB->data[bl]),buf,i);

dataB->data[bl+i]='\0';

bl+=i;

if (end)

{

buf[0]='\0';

i=BIO_gets(bp,buf,254);

if (i <= 0) break;

 

while ((i >= 0) && (buf[i] <= ' ')) i--;

buf[++i]='\n'; buf[++i]='\0';

 

break;

}

}

}

else

{

tmpB=headerB;

headerB=dataB;

dataB=tmpB;

bl=hl;

}

i=strlen(nameB->data);

if ((strncmp(buf,"-----END ",9) != 0) ||

(strncmp(nameB->data,&(buf[9]),i) != 0) ||

(strncmp(&(buf[9+i]),"-----\n",6) != 0))

{

PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE);

goto err;

}

 

EVP_DecodeInit(&ctx);

i=EVP_DecodeUpdate(&ctx,

(unsigned char *)dataB->data,&bl,

(unsigned char *)dataB->data,bl);

if (i < 0)

{

PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);

goto err;

}

i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);

if (i < 0)

{

PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);

goto err;

}

bl+=k;

 

if (bl == 0) goto err;

*name=nameB->data;

*header=headerB->data;

*data=(unsigned char *)dataB->data;

*len=bl;

OPENSSL_free(nameB);

OPENSSL_free(headerB);

OPENSSL_free(dataB);

return(1);

err:

BUF_MEM_free(nameB);

BUF_MEM_free(headerB);

BUF_MEM_free(dataB);

return(0);

}

 

 

int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,

    long *len)

        {

        BIO *b;

        int ret;

 

        if ((b=BIO_new(BIO_s_file())) == NULL)

{

PEMerr(PEM_F_PEM_READ,ERR_R_BUF_LIB);

                return(0);

}

        BIO_set_fp(b,fp,BIO_NOCLOSE);

        ret=PEM_read_bio(b, name, header, data,len);

        BIO_free(b);

        return(ret);

        }

 

附录 A ASN.1语法

 

A.1 RSA 密钥描述

 

A.1.1 RSA 公钥语法

 

RSAPublicKey ::= SEQUENCE {

modulus           INTEGER,  -- n

publicExponent    INTEGER   -- e

}

 

A.1.2 RSA 私钥语法

 

RSAPrivateKey ::= SEQUENCE {

version           Version,

modulus           INTEGER,  -- n

publicExponent    INTEGER,  -- e

privateExponent   INTEGER,  -- d

prime1            INTEGER,  -- p

prime2            INTEGER,  -- q

exponent1         INTEGER,  -- d mod (p-1)

exponent2         INTEGER,  -- d mod (q-1)

coefficient       INTEGER,  -- (inverse of q) mod p

otherPrimeInfos   OtherPrimeInfos OPTIONAL

}

 

 

A.2 体系验证

 

Java RSA加密解密实例

private static RSAPrivateKey privateKey = null;
private static byte[] privateKeyEncoded = null;

private static RSAPublicKey publicKey = null;
private static byte[] publicKeyEncoded = null;

@BeforeClass
public static void init() /* throws NoSuchAlgorithmException */ {
    KeyPairGenerator keyPairGenerator = null;
    try {
        keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    }
    keyPairGenerator.initialize(512);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();

    privateKey = (RSAPrivateKey) keyPair.getPrivate();
    publicKey = (RSAPublicKey) keyPair.getPublic();

    privateKeyEncoded = ((Key) privateKey).getEncoded();
    publicKeyEncoded = ((Key) publicKey).getEncoded();
    System.out.println("private key: " + Base64.byteArrayToBase64(privateKeyEncoded));
    System.out.println("public key: " + Base64.byteArrayToBase64(publicKeyEncoded));
}

 

加密解密

@org.junit.Test
public void test() {
    String message = "13120983870";
    System.out.println(message);

    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyEncoded);
    KeyFactory keyFactory = null;
    try {
        keyFactory = KeyFactory.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    }

    PrivateKey privateKey = null;
    try {
        privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    } catch (InvalidKeySpecException e) {
        Assert.fail("invalid key spec: " + e.getMessage());
    }
    System.out.println("private key: " + Base64.byteArrayToBase64(((Key) privateKey).getEncoded()));

    Cipher cipher = null;
    try {
        cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    } catch (NoSuchPaddingException e) {
        Assert.fail("no such padding: " + e.getMessage());
    }
    try {
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    } catch (InvalidKeyException e) {
        Assert.fail("invalid key: " + e.getMessage());
    }

    byte[] encryption = null;
    try {
        encryption = cipher.doFinal(message.getBytes());
    } catch (IllegalBlockSizeException e) {
        Assert.fail("illegal block size: " + e.getMessage());
    } catch (BadPaddingException e) {
        Assert.fail("bad padding: " + e.getMessage());
    }
    System.out.println("encryption: " + Base64.byteArrayToBase64(encryption));


    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyEncoded);
    try {
        keyFactory = KeyFactory.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    }
    PublicKey publicKey = null;
    try {
        publicKey = keyFactory.generatePublic(x509KeySpec);
    } catch (InvalidKeySpecException e) {
        Assert.fail("invalid key spec: " + e.getMessage());
    }
    System.out.println("public key: " + Base64.byteArrayToBase64(((Key) publicKey).getEncoded()));
    try {
        cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    } catch (NoSuchPaddingException e) {
        Assert.fail("no such padding: " + e.getMessage());
    }
    try {
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
    } catch (InvalidKeyException e) {
        Assert.fail("invalid key: " + e.getMessage());
    }

    byte[] decryption = null;
    try {
        decryption = cipher.doFinal(encryption);
    } catch (IllegalBlockSizeException e) {
        Assert.fail("illegal block size: " + e.getMessage());
    } catch (BadPaddingException e) {
        Assert.fail("bad padding: " + e.getMessage());
    }
    System.out.println("decryption: " + new String(decryption) + ", base64:" + Base64.byteArrayToBase64(decryption));
}

 

 

/**
 * 使用私钥加密,再使用公钥解密
 */
@org.junit.Test
public void test1() {
    String message = "13120983870";
    System.out.println(message);

    // 加密
    Cipher cipher = null;
    try {
        cipher = Cipher.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    } catch (NoSuchPaddingException e) {
        Assert.fail("no such padding: " + e.getMessage());
    }
    try {
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    } catch (InvalidKeyException e) {
        Assert.fail("invalid key: " + e.getMessage());
    }

    byte[] encryption = null;
    try {
        encryption = cipher.doFinal(message.getBytes());
    } catch (IllegalBlockSizeException e) {
        Assert.fail("illegal block size: " + e.getMessage());
    } catch (BadPaddingException e) {
        Assert.fail("bad padding: " + e.getMessage());
    }
    System.out.println("encryption: " + Base64.byteArrayToBase64(encryption));

    // 解密
    try {
        cipher = Cipher.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    } catch (NoSuchPaddingException e) {
        Assert.fail("no such padding: " + e.getMessage());
    }
    try {
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
    } catch (InvalidKeyException e) {
        Assert.fail("invalid key: " + e.getMessage());
    }

    byte[] decryption = null;
    try {
        decryption = cipher.doFinal(encryption);
    } catch (IllegalBlockSizeException e) {
        Assert.fail("illegal block size: " + e.getMessage());
    } catch (BadPaddingException e) {
        Assert.fail("bad padding: " + e.getMessage());
    }
    System.out.println("decryption: " + new String(decryption) + ", base64:" + Base64.byteArrayToBase64(decryption));
}

 

private key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAhLKv2wOrV2BGqXxRyrLSJ6jzMey1kxuthXFO+EBjiI7GuTxYpr6lXxyrfnwuhBz0OrXS4QatE9PT2JudFWMsSQIDAQABAkBSNtM1goR50jB1eYzDZR9Haymh2OJ2jkNn1dfzfxEr3UTjlhv42v7FfmLWl0TISEuW5AxZyZBFHhWP7YNF3RYBAiEAxRixL6dmIpRxndVxcCvml16Cn3J+NDkRyWmzwS0WyXECIQCsWwu6+P88wUEOFTgQ/Z5EQFkCXm5h6dL/EmhUordkWQIgTCvuzmvznQmhn04OOTu+MmHkOZsWCzjDFwQy5EV4uQECIEwTN79EbmxjpJJRvViKiVP4zxDjm3cuXQpnFpPc6nOpAiAEiLzfZvzCI4Vx3KxGrOLxaTWC9KbpCG3IRsLBMN/EqA==
public key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAISyr9sDq1dgRql8Ucqy0ieo8zHstZMbrYVxTvhAY4iOxrk8WKa+pV8cq358LoQc9Dq10uEGrRPT09ibnRVjLEkCAwEAAQ==
13120983870
encryption: ZVT1Gt5cP/KHmogMcWU0TxLm1hYqRXzqsvLCvQr9pDgjVA+yzXM6IWZSdXf2dm+j9XeGS72bHayOIo7Py+tEbQ==
decryption: 13120983870, base64:MTMxMjA5ODM4NzA=

 

Java RSA数字签名实例

 

/**
 * private key: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApTHMs+zR16SE0v3npoVbMGo70xX5tJ7HF23SvM2rARkJNtRs4xZRQpWQ1JBZnGna9HcVQsrRAORqYhhTrZ9rMQIDAQABAkAFNrlYrasZErJGQEEiIWP9lwHCvZchLTB4j+TahIV+2iLTiLa21QOqQFmpBqw/uqmHsJGtqtHIXdtgCrGtoLVhAiEA4zpbZ52vkCskvZ2eJ34n6dTsiybZLIMYIdp21kd6mpECIQC6HJ2f0R6BwL/ORYhF6tA1YeXZEKyAuTgDkwgmGN/WoQIgPsXrZHeafbB9iOiXPX/LlPyekF6eFn7s1sVcmRvMEhECIBnJDS2vU4K2qdxyVccaGW7L+YRxgvTytIgKPv7IQ3sBAiEAh3XrxyuR3nJhFD5pPcRLmnst9Ag6WQuthc/SgkKJlXk=
 * public key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKUxzLPs0dekhNL956aFWzBqO9MV+bSexxdt0rzNqwEZCTbUbOMWUUKVkNSQWZxp2vR3FULK0QDkamIYU62fazECAwEAAQ==
 */
@Test
public void signAndVerityWithEncoded0() {
    String privateKey = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApTHMs+zR16SE0v3npoVbMGo70xX5tJ7HF23SvM2rARkJNtRs4xZRQpWQ1JBZnGna9HcVQsrRAORqYhhTrZ9rMQIDAQABAkAFNrlYrasZErJGQEEiIWP9lwHCvZchLTB4j+TahIV+2iLTiLa21QOqQFmpBqw/uqmHsJGtqtHIXdtgCrGtoLVhAiEA4zpbZ52vkCskvZ2eJ34n6dTsiybZLIMYIdp21kd6mpECIQC6HJ2f0R6BwL/ORYhF6tA1YeXZEKyAuTgDkwgmGN/WoQIgPsXrZHeafbB9iOiXPX/LlPyekF6eFn7s1sVcmRvMEhECIBnJDS2vU4K2qdxyVccaGW7L+YRxgvTytIgKPv7IQ3sBAiEAh3XrxyuR3nJhFD5pPcRLmnst9Ag6WQuthc/SgkKJlXk=";
    String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKUxzLPs0dekhNL956aFWzBqO9MV+bSexxdt0rzNqwEZCTbUbOMWUUKVkNSQWZxp2vR3FULK0QDkamIYU62fazECAwEAAQ==";

    byte[] privateKeyEncoded = Base64.base64ToByteArray(privateKey);
    byte[] publicKeyEncoded = Base64.base64ToByteArray(publicKey);

    String message = "13120983870";
    System.out.println(message);

    signAndVerity(message, privateKeyEncoded, publicKeyEncoded);
}

 

private void signAndVerity(String message, byte[] privateKeyEncoded, byte[] publicKeyEncoded) {
    // 签名
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyEncoded);
    KeyFactory keyFactory = null;
    try {
        keyFactory = KeyFactory.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    }

    PrivateKey privateKey = null;
    try {
        privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    } catch (InvalidKeySpecException e) {
        Assert.fail("invalid key spec: " + e.getMessage());
    }
    System.out.println("private key: " + Base64.byteArrayToBase64(((Key) privateKey).getEncoded()));

    Signature signature = null;
    try {
        signature = Signature.getInstance("MD5withRSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    }
    try {
        signature.initSign(privateKey);
    } catch (InvalidKeyException e) {
        Assert.fail("invalid key: " + e.getMessage());
    }

    byte[] sign = null;
    try {
        signature.update(message.getBytes());
        sign = signature.sign();
    } catch (SignatureException e) {
        Assert.fail("signature: " + e.getMessage());
    }
    System.out.println("signature: " + Base64.byteArrayToBase64(sign));

    // 验证
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyEncoded);
    try {
        keyFactory = KeyFactory.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        Assert.fail("no such algorithm: " + e.getMessage());
    }
    PublicKey publicKey = null;
    try {
        publicKey = keyFactory.generatePublic(x509KeySpec);
    } catch (InvalidKeySpecException e) {
        Assert.fail("invalid key spec: " + e.getMessage());
    }
    System.out.println("public key: " + Base64.byteArrayToBase64(((Key) publicKey).getEncoded()));
    try {
        signature.initVerify(publicKey);
    } catch (InvalidKeyException e) {
        Assert.fail("invalid key: " + e.getMessage());
    }

    byte[] decryption = null;
    try {
        signature.update(message.getBytes());
        boolean result = signature.verify(sign);
        Assert.assertTrue(result);
    } catch (SignatureException e) {
        Assert.fail("signature: " + e.getMessage());
    }
}

 

private key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA36Luv7yDI5RCnvC/d8HFvqXHa5Iry2bBX1qDo2KQkzlMzr5mVnMCk3WOA49PVyQ9EPJa7kIrfRlSdp38R3FB1wIDAQABAkA5nUxM8VAHtoaDVBq/y5gaSbNar0nBGTPwUO1hBl+gzcMGgPEw4F1DaYelt+dUxbD7po4OPiiHz/F5+HJAV5SBAiEA72yOz+HfhCqkvQ5l4dSIpoSmfcw05CxnMBe2p+FtskcCIQDvHpAGQ8po0l0NIgyK+bUIuuHDOUb5ePWtiA4kSrGr8QIgWfgONlnndy/bFdv6NwF5lDFWqwD4gyGYaP8QOUfBw/MCIBQJx5/+xlOKbWnQVKTA0D7vCkRF5IC7djsYj7bS25jBAiAS/IX4KRsV9TayXXDeuqaD8Z+ONQ/98xJwAabcNAmXrA==
public key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAN+i7r+8gyOUQp7wv3fBxb6lx2uSK8tmwV9ag6NikJM5TM6+ZlZzApN1jgOPT1ckPRDyWu5CK30ZUnad/EdxQdcCAwEAAQ==
13120983870
private key: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApTHMs+zR16SE0v3npoVbMGo70xX5tJ7HF23SvM2rARkJNtRs4xZRQpWQ1JBZnGna9HcVQsrRAORqYhhTrZ9rMQIDAQABAkAFNrlYrasZErJGQEEiIWP9lwHCvZchLTB4j+TahIV+2iLTiLa21QOqQFmpBqw/uqmHsJGtqtHIXdtgCrGtoLVhAiEA4zpbZ52vkCskvZ2eJ34n6dTsiybZLIMYIdp21kd6mpECIQC6HJ2f0R6BwL/ORYhF6tA1YeXZEKyAuTgDkwgmGN/WoQIgPsXrZHeafbB9iOiXPX/LlPyekF6eFn7s1sVcmRvMEhECIBnJDS2vU4K2qdxyVccaGW7L+YRxgvTytIgKPv7IQ3sBAiEAh3XrxyuR3nJhFD5pPcRLmnst9Ag6WQuthc/SgkKJlXk=
signature: YVuyrhVPkQhydhWWe9+TMAPnDCRVpy3mM0Q2tDQsWhJTOntYlH7t7/ENj76flzOmXr6zSfNZX6Qnh2SbRQkm+Q==
public key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKUxzLPs0dekhNL956aFWzBqO9MV+bSexxdt0rzNqwEZCTbUbOMWUUKVkNSQWZxp2vR3FULK0QDkamIYU62fazECAwEAAQ==

 

 

1、PKCS #1: RSA Encryption Version 1.5,https://www.rfc-editor.org/rfc/rfc2313.txt

2、PKCS #1: RSA Cryptography Specifications Version 2.0,https://www.ietf.org/rfc/rfc2437.txt

3、Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1,https://www.rfc-editor.org/rfc/rfc3447.txt

4、https://people.cs.umass.edu/~emery/classes/cmpsci691st/scribe/lecture14-rsa.pdf

5、https://en.wikipedia.org/wiki/RSA_(cryptosystem)

6、https://en.wikipedia.org/wiki/RSA

7、PEM, Privacy Enhancement for Internet Electronic Mail: Part I: Message Encipherment and Authentication Procedures, https://www.rfc-editor.org/rfc/rfc1040.txt

8、PEM, Privacy Enhancement for Internet Electronic Mail: Part I -- Message Encipherment and Authentication Procedures, https://www.rfc-editor.org/rfc/rfc1113.txt

9、PEM,Privacy Enhancement for Internet Electronic Mail: Part I: Message Encryption and Authentication Procedures,https://www.rfc-editor.org/rfc/rfc1421.txt

10、PEM, Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management, https://www.rfc-editor.org/rfc/rfc1422.txt

11、PEM, Privacy Enhancement for Internet Electronic Mail: Part III: Algorithms, Modes, and Identifiers, https://www.rfc-editor.org/rfc/rfc1423.txt

12、PEM, Privacy Enhancement for Internet Electronic Mail: Part IV: Key Certification and Related Services, https://www.rfc-editor.org/rfc/rfc1424.txt

 

你可能感兴趣的:(RSA的一些资料)