
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子命令用法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)