从字符串中解析私钥并rsa解密

从字符串中解析私钥并rsa解密,第1张

Parse RSA public and private key pair from string in Java

逆向某APP,发现其大部分配置文件都是加密的 。所以逆向算法并解密

RSA和AES密钥 可以分析WTDefine发现,WTDefine是一个单例模式的加密。所以我们找到初始化的那个地方就行

写个java

分类: 电脑/网络 >> 互联网

解析:

RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

RSA的算法涉及三个参数,n、e1、e2。

其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。

e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)(q-1)互质;再选择e2,要求(e2e1)mod((p-1)(q-1))=1。

(n及e1),(n及e2)就是密钥对。

RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e1 mod n;B=A^e2 mod n;

e1和e2可以互换使用,即:

A=B^e2 mod n;B=A^e1 mod n;

补充回答:

对明文进行加密,有两种情况需要这样作:

1、您向朋友传送加密数据,您希望只有您的朋友可以解密,这样的话,您需要首先获取您朋友的密钥对中公开的那一个密钥,e及n。然后用这个密钥进行加密,这样密文只有您的朋友可以解密,因为对应的私钥只有您朋友拥有。

2、您向朋友传送一段数据附加您的数字签名,您需要对您的数据进行MD5之类的运算以取得数据的"指纹",再对"指纹"进行加密,加密将使用您自己的密钥对中的不公开的私钥。您的朋友收到数据后,用同样的运算获得数据指纹,再用您的公钥对加密指纹进行解密,比较解密结果与他自己计算出来的指纹是否一致,即可确定数据是否的确是您发送的、以及在传输过程中是否被篡改。

密钥的获得,通常由某个机构颁发(如CA中心),当然也可以由您自己创建密钥,但这样作,您的密钥并不具有权威性。

计算方面,按公式计算就行了,如果您的加密强度为1024位,则结果会在有效数据前面补0以补齐不足的位数。补入的0并不影响解密运算。

genrsa、rsa、req、x509子命令主要用于RSA密钥的生成和处理,以及证书的申请和制作。

genrsa子命令主要用于生成RSA私钥。

openssl genrsa [args] [numbits]

-des 使用des cbc模式对私钥文件进行加密。

-des3 使用des3 cbc模式对私钥文件进行加密。

-idea 使用idea cbc模式对私钥文件进行加密。

-aes128, -aes192, -aes256 使用aes cbc模式对私钥文件进行加密。

-out file 指定输出私钥文件名。

-f4 指定F4做为E值,默认。

-3 指定3做为E值。

-seed arg 指定cbc的随机种子。

-rand file:file 指定随机数种子文件。

rsa子命令主要用于处理RSA公私钥文件。

openssl rsa [options] <infile >outfile

-inform arg 指定输入文件格式,可以为DER或PEM,默认为PEM。

-outform arg 指定输出文件格式,可以为DER或PEM,默认为PEM。

-in arg 指定输入文件。

-out arg 指定输出文件。

-pubin 指定输入文件为公钥,默认为私钥。

-pubout 指定输出文件为公钥,默认为私钥。

-passin arg 指定输入文件的口令保护来源。

-passout arg 指定输出文件的口令保护来源。

-des 使用des cbc模式对输出文件进行加密。

-des3 使用des3 cbc模式对输出文件进行加密。

-idea 使用idea cbc模式对输出文件进行加密。

-aes128, -aes192, -aes256 使用aes cbc模式对输出文件进行加密。

-text 打印密钥信息。

-noout 不向控制台打印密钥信息。

-modulus 打印RSA的模数信息。

-check 检查RSA私钥的有效性。

req子命令主要用于创建证书请求文件。

openssl req [options] <infile >outfile

-inform arg 指定输入文件格式,可以为DER或PEM,默认为PEM。

-outform arg 指定输出文件格式,可以为DER或PEM,默认为PEM。

-in arg 指定输入文件。

-out arg 指定输出文件。

-new 创建新的证书请求文件。

-key file 指定创建证书请求的私钥文件。

-keyform arg 指定创建证书请求的私钥文件的格式,可以为DER或PEM,默认为PEM。

-passin arg 指定私钥文件的口令保护来源。

-verify 校验证书请求文件的主体签名是否有效。

-noout 不打印证书请求信息。

-text 文本打印证书请求文件。

-modulus 输出证书请求的模数信息。

-subject 输出证书请求主体信息。

-subj arg 设置或修改证书请求的主体信息。

-multivalue-rdn 设置或修改证书请求的主体信息时,允许多RDN格式。

-utf8 输入字符为utf8编码,默认输入为ASCII编码。

-[digest] 指定创建证书请求的摘要算法。

-pubkey 提取证书请求文件中的公钥。

x509命令主要用于创建、修改x509证书。

openssl x509 [options] <infile >outfile

-inform arg 指定输入文件格式,可以为DER或PEM,默认为PEM。

-outform arg 指定输出文件格式,可以为DER或PEM,默认为PEM。

-keyform arg 指定私钥文件格式,可以为DER或PEM,默认为PEM。

-CAform arg 指定CA文件格式,可以为DER或PEM,默认为PEM。

-CAkeyform arg 指定CA私钥文件格式,可以为DER或PEM,默认为PEM。

-in arg 指定输入文件,默认为标准输入。

-out arg 指定输出文件,默认为标准输出。

-passin arg 指定私钥文件的口令保护来源。

-pubkey 提取持有者公钥。

-trustout 提取可信任证书。

-noout 不向控制台输出证书信息。

-text 打印证书信息。

-C 以C证言格式打印证书信息。

-serial 打印证书的序列号。

-subject_hash 打印持有者的摘要。

-issuer_hash 打印颁发者的摘要。

-hash 等同于-subject_hash。

-subject 打印持有者的DN信息。

-issuer 打印颁发者的DN信息。

-email 打印email地址。

-startdate 打印证书的生效时间。

-enddate 打印证书的失效时间。

-dates 打印证书的有效期。

-purpose 打印证书用途。

-modulus 打印证书中的RSA模数。

-fingerprint 打印证书微缩图。

-alias 打印证书别名。

-ocspid 打印持有者和公钥的OCSP摘要值。

-clrtrust 清除证书附加项里所有有关用途允许的内容。

-clrreject 清除证书附加项里所有有关用途禁止的内容。

-addtrust arg 添加证书附加项里所有有关用途允许的内容。

-addreject arg 添加证书附加项里所有有关用途禁止的内容。

-setalias arg 设置证书别名。

-days arg 设置证书有效期,默认30天。

-checkend arg 检查证书在给定的arg秒后是否还有效。

-signkey arg 指定自签名私钥文件。

-x509toreq 根据证书来生成证书请求,需要指定签名私钥。

-req 输入文件为证书请求。

-CA arg 设置CA文件,必须为PEM格式。

-CAkey arg 设置CA私钥文件,必须为PEM格式。

-CAcreateserial 创建序列号文件。

-CAserial arg 指定序列号文件。

-set_serial 设置证书序列号。

-<dgst> 指定使用的摘要算法,缺省为MD5。

从自己编写程序实现以上子命令的角度考虑,涉及RSA生成、存取API,涉及PEM读写,以及X509相关的数据格式的理解,总体来说要求还是挺高的,有兴趣的朋友可以尝试下。

网络数据的传输一般都是用对称加密算法

非对称加密算法因为效率的问题只用来加密 对称加密算法 的秘钥和 用于 数字签名

*** 作前 服务器和客户端都已拥有双方的公钥

Android的RSA公钥-->发送给服务器用

服务器的RSA公钥-->发送给客户端用

如客户端验证服务器的真实性

Android客户端(拥有AES秘钥)

使用 非对称加密算法即 服务器的RSA公钥 Android客户端的AES的秘钥 进行加密

然后 >

#include <openssl/rsah>

#include <openssl/shah>

int main()

{

RSA r;

int bits=1024,ret,len,flen,padding,i;

unsigned long e=RSA_3;

BIGNUM bne;

unsigned charkey,p;

BIO b;

unsigned charfrom[500],to[500],out[500];

bne=BN_new();

ret=BN_set_word(bne,e);

r=RSA_new();

ret=RSA_generate_key_ex(r,bits,bne,NULL);

if(ret!=1)

{

printf("RSA_generate_key_ex err!\n");

return -1;

}

/ 私钥i2d /

b=BIO_new(BIO_s_mem());

ret=i2d_RSAPrivateKey_bio(b,r);

key=malloc(1024);

len=BIO_read(b,key,1024);

BIO_free(b);

b=BIO_new_file("rsakey","w");

ret=i2d_RSAPrivateKey_bio(b,r);

BIO_free(b);

/ 私钥d2i /

/ 公钥i2d /

/ 公钥d2i /

/ 私钥加密 /

flen=RSA_size(r);

printf("please select private enc padding : \n");

printf("1RSA_PKCS1_PADDING\n");

printf("3RSA_NO_PADDING\n");

printf("5RSA_X931_PADDING\n");

scanf("%d",&padding);

if(padding==RSA_PKCS1_PADDING)

flen-=11;

else if(padding==RSA_X931_PADDING)

flen-=2;

else if(padding==RSA_NO_PADDING)

flen=flen;

else

{

printf("rsa not surport !\n");

return -1;

}

for(i=0;i<flen;i++)

memset(&from[i],i,1);

len=RSA_private_encrypt(flen,from,to,r,padding);

if(len<=0)

{

printf("RSA_private_encrypt err!\n");

return -1;

}

len=RSA_public_decrypt(len,to,out,r,padding);

if(len<=0)

{

printf("RSA_public_decrypt err!\n");

return -1;

}

if(memcmp(from,out,flen))

{

printf("err!\n");

return -1;

}

/ /

printf("please select public enc padding : \n");

printf("1RSA_PKCS1_PADDING\n");

printf("2RSA_SSLV23_PADDING\n");

printf("3RSA_NO_PADDING\n");

printf("4RSA_PKCS1_OAEP_PADDING\n");

scanf("%d",&padding);

flen=RSA_size(r);

if(padding==RSA_PKCS1_PADDING)

flen-=11;

else if(padding==RSA_SSLV23_PADDING)

flen-=11;

else if(padding==RSA_X931_PADDING)

flen-=2;

else if(padding==RSA_NO_PADDING)

flen=flen;

else if(padding==RSA_PKCS1_OAEP_PADDING)

flen=flen-2 SHA_DIGEST_LENGTH-2 ;

else

{

printf("rsa not surport !\n");

return -1;

}

for(i=0;i<flen;i++)

memset(&from[i],i+1,1);

len=RSA_public_encrypt(flen,from,to,r,padding);

if(len<=0)

{

printf("RSA_public_encrypt err!\n");

return -1;

}

len=RSA_private_decrypt(len,to,out,r,padding);

if(len<=0)

{

printf("RSA_private_decrypt err!\n");

return -1;

}

if(memcmp(from,out,flen))

{

printf("err!\n");

return -1;

}

printf("test ok!\n");

RSA_free(r);

return 0;

}

上述程序中当采用公钥RSA_SSLV23_PADDING加密,用私钥RSA_SSLV23_PADDING解密时会报错,原因是openssl源代码错误:

rsa_sslc函数RSA_padding_check_SSLv23有:

if (k == -1) / err /

{

RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_SSLV3_ROLLBACK_ATTACK);

return (-1);

}

修改为k!=-1即可。

各种padding对输入数据长度的要求:

私钥加密:

RSA_PKCS1_PADDING RSA_size-11

RSA_NO_PADDING RSA_size-0

RSA_X931_PADDING RSA_size-2

公钥加密

RSA_PKCS1_PADDING RSA_size-11

RSA_SSLV23_PADDING RSA_size-11

RSA_X931_PADDING RSA_size-2

RSA_NO_PADDING RSA_size-0

RSA_PKCS1_OAEP_PADDING RSA_size-2 SHA_DIGEST_LENGTH-2

这里边涉及到几个概念。其实我们无法从私钥中获得公钥的!就象我们无法通过公钥获得私钥一样!但事实上保存私钥的文件并不单单保存了私钥,它非本身是保存的有公钥的!也就是说如果一个证书文件只含有公钥时,那就是只有公钥,如果含有私有时一定会含有公钥——并不是你想象的只有一个私钥。

现在来说一下RSA机制,我们知道,RSA基于两个大素数之积,所以,一个正常的容器内包含有几个基本的参数的(RSAParameters类):

d /dp/dq/Expoent/InverseQ/Modulus/p/q

如果是保存私钥时,这几个参数会全部存在,但如果只是一个公钥文件的话,只有n/e(Modulus和Exponent)两个参数是存在的。

所以一般我们使用是否含有私钥作为文件或容量的参数,从另一个角度上来说,一定是存在公钥的,但是否存在私钥做为一个参数。

当然这个内容与具体的语言没有关系——所有的RSA都是这样规定的。

1、加米解米的第一步是生成公钥、私钥对,私钥加米的内容能通过公钥解米(反过来亦可以)下载开源RSA米钥生成工具openssl(通常Linux系统都自带该程序),解压缩至独立的文件夹,进入其中的bin目录,执行以下命令: 复制代码 代码如下: openssl

以上就是关于从字符串中解析私钥并rsa解密全部的内容,包括:从字符串中解析私钥并rsa解密、什么是RSA算法,有公钥和私钥对他的处理过程是这样的、OpenSSL之genrsa&rsa&req&x509子命令用法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9561343.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存