加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

OpenSSL RSA密钥相关命令

(2016-11-23 14:45:45)
标签:

rsa

openssl

分类: Security
OpenSSL中RSA算法指令主要有三个:
  genrsa      生成RSA密钥
  rsa            处理RSA密钥的格式转换等问题
  rsautl        使用RSA密钥进行加密、解密、签名和验证等运算

1.生成RSA密钥命令
    $ openssl genrsa –out rsa2048.pem 2048
       -out 指定生成文件,包含公钥和私钥。
    注:OpenSSL 1.0.1f 6 Jan 2014 默认以PKCS#1 RSAPrivateKey结构标准输出。
PEM私钥格式文件:
                 -----BEGIN RSA PRIVATE KEY-----
                 BASE64私钥内容
                 -----END RSA PRIVATE KEY-----
二进制格式文件解析:
          2048                                                                1024
    标签头:3082                                                    标签头:3082
    长   度:04a4  即后接1188字节数据                   长   度:0278  即后接632字节数据
    版   本:020100                                                 版   本:020100
                 02 - tag
                 01 - length
                 00 - value
    RSA_N:02820101 + 00 + data                        RSA_N:028181 + 00 + data
                  02 - tag
                  82 - 81代表长度用1字节表示,82代表长度用2字节表示
                  0101 - 长度,257字节                                        81 - 长度,129字节
                  00 - 未知
    RSA_D :  02820101 + 00 + data                       RSA_D :  028181 + 00 + data
    RSA_p :  028181 + 00 + data                            RSA_P :  028141 + 00 + data
    RSA_q :  028181 + 00 + data                            RSA_q :  028141 + 00 + data
    RSA_E :0203010001                                        RSA_E :0203010001
                  02 - tag
                  03 - length
                  010001 - value 65537
-----------------------------------------------------------------------------------------------------------------
2.提取PEM格式RSA公钥命令
    $ openssl rsa –in rsa2048.pem –pubout –out rsa2048_pub.pem
     注:OpenSSL 1.0.1f 6 Jan 2014 默认以SubjectPublicKeyInfo结构标准输出。
PEM公钥格式文件:
                 -----BEGIN PUBLIC KEY-----
                 BASE64公钥内容
                 -----END PUBLIC KEY-----    
二进制格式文件解析:以2048为例
    标签头:3082
    长   度:010a  即后接266字节数据
          --->实际为0122300d06092a864886f70d01010105000382010f003082010a
          其中24字节数据估计为 const RSA_METHOD *meth;
                                      ENGINE *engine;
    RSA_N:02820101 + 00 + data
                  02 - tag
                  82 - 81代表长度用1字节表示,82代表长度用2字节表示
                  0101 - 长度,257字节                                        81 - 长度,129字节
                  00 - 未知
    RSA_E :0203010001
                  02 - tag
                  03 - length
                  010001 - value 65537
公钥读取函数:
        RSA *PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL)) 如果公钥类型不是RSA,返回读取失败信息。
-----------------------------------------------------------------------------------------------------------------
3.提取PEM RSAPublicKey格式公钥命令
    $ openssl rsa –in rsa2048.pem –RSAPublicKey_out –out rsa2048_public.pem
      注:OpenSSL 1.0.1f 6 Jan 2014 以PKCS#1 RSAPublicKey 结构标准输出。
                -----BEGIN RSA PUBLIC KEY-----
                BASE64公钥内容
                -----END RSA PUBLIC KEY-----
二进制格式文件解析:
          2048                                                                1024
    标签头:3082                                                    标签头:3082
    长   度:010a  即后接266字节数据                     长   度:
    RSA_N:02820101 + 00 + data                        RSA_N:028181 + 00 + data
                  02 - tag
                  82 - 81代表长度用1字节表示,82代表长度用2字节表示
                  0101 - 长度,257字节                                        81 - 长度,129字节
                  00 - 未知
    RSA_E :0203010001                                        RSA_E :0203010001
                  02 - tag
                  03 - length
                  010001 - value 65537
公钥读取函数:
        RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x,pem_password_cb *cb, void *u);
-----------------------------------------------------------------------------------------------------------------
4.生成的RSA 公/私钥文件为base64编码,将其转换成二进制编码
     //base64转换成16进制格式
    $ openssl base64 –d –in base64.txt –out hex.txt
    $ openssl base64 –d –in rsa2048.pem –out rsa2048.bin
     //16进制转换成base64格式
    $ openssl base64 –in hex.txt –out base64.txt
5.明文形式输出密钥的各个参数值
    $ openssl rsa –in rsa2048.pem –text –out rsa2048.txt
-----------------------------------------------------------------------------------------------------------------
6.RSA密钥语法
在PKCS#1 RSA算法标准中,定义RSA私钥语法为:
RSAPrivateKey ::= SEQUENCE {
    version Version,                                                      版本号    默认为0,使用多素数为1
    modulus INTEGER,             --n                                RSA的合数模n=p*q
    publicExponent INTEGER,  --e                                RSA的公开幂e
    privateExponent INTEGER, --d                                RSA的私有幂d
    prime1 INTEGER,                --p                                n的素数因子p
    prime2 INTEGER,                --q                                n的素数因子q
    exponent1 INTEGER,          --d mod (p-1)             
    exponent2 INTEGER,          --d mod (q-1)
    coefficient INTEGER,          --(inverse of q) mod p  CRT系数q-1 mod p
    otherPrimeInfos OtherPrimeInfos OPTIONAL         使用此项,版本号为1。
}

otherPrimeInfos ::= SEQUENCE {
    prime INTEGER,          --ri    n的一个素数因子,其中i>=3。
    exponent INTEGER,    --di   di = d mod (ri - 1)
    coefficient INTEGER    --ti   CRT系数 ti = (r1 * r2 * ... * ri-1)-1 mod ri
}

公钥语法为:
RSAPublicKey ::= SEQUENCE {
    modulus INTEGER,              --n    RSA的合数模n
    publicExponent INTEGER    --e    RSA的公开幂
}
-----------------------------------------------------------------------------------------------------------------
rsautl指令说明
RSA每次能够加密的数据长度不能超过RSA密钥长度,并且根据具体的补齐方式不同输入的加密数据最大长度也不一样,而输出长度则总是跟RSA密钥长度相等。
     数据补齐方式                  输入数据长度             输出数据长度    参数字符串         填充方式宏定义
    PKCS#1 v1.5(默认 小于(密钥长度-11)字节     同密钥长度        -pkcs        RSA_PKCS1_PADDING 1
    PKCS#1 OAEP        小于(密钥长度-11)字节     同密钥长度        -oaep    RSA_PKCS1_OAEP_PADDING 4 PKCS#1 for SSLv23    小于(密钥长度-11)字节     同密钥长度         -ssl
      不使用补齐                      同密钥长度                 同密钥长度         -raw          RSA_NO_PADDING 3

7.RSA公钥加密
    //使用RSA公钥加密
    $ openssl rsautl -encrypt -in plain.txt -inkey pub.pem -pubin -out enc.txt
        -pubin 指定输入的是RSA公钥
        -certin 指定输入的是证书文件
    //使用RSA密钥加密,实际上使用其中的公钥加密
    $ openssl rsautl -encrypt -in plain.txt -inkey RSA.pem -out enc.txt
8.RSA私钥解密
    //使用RSA密钥解密,实际上使用其中的私钥解密
    $ openssl rsautl -decrypt -in enc.txt -inkey RSA.pem -out replain.txt
    $ diff plain.txt replain.txt        //比较原始文件和解密后文件
9.RSA私钥签名
     //使用RSA密钥签名,实际上使用其中的私钥加密
    $ openssl rsautl -sign -in plain.txt -inkey RSA.pem -out sign.txt

    //提取PCKS8格式的私钥
    $ openssl pkcs8 -topk8 -in RSA.pem -out pri.pem -nocrypt
     //使用RSA私钥签名
    $ openssl rsautl -sign -in plain.txt -inkey pri.pem -out sign.txt
    -------------------------------------------------------------------------------------------------
    注意:开发代码与Linux openssl签名结果比较验证时需注意!
              签名输入文件-in plain.txt,openssl读取以16进制格式读取输入。
              新建文件,输入16进制数据文本,并不是openssl签名的16进制数据。
              通过open write函数,写入16进制数据到文件才是纯16进制文件。
            
Android.mk -->生成可执行模块 LOCAL_MODULE := sign
.c文件:要包含openssl相关头文件
int signimg(char *in, char *out, char *key_path)
{
int i;
int fd = 0;
int hash_data_len = 36;   //test hash_data len
char *key[2] = { 0 };
char *hash_data = NULL;  //哈希文件指针
char *hash_sign = NULL;   //签名文件
char  data[256];
uint8_t signature[256];

for(i=0;i<256;i++)  //赋值
data[i]=i+6;
        hash_data = in;
hash_sign = out;

printf("input image name is:%s\n",in);
for (i = 0; i < 2; i++) {
key[i] = (char *)malloc(NAME_MAX_LEN);
if (key[i] == 0)
goto fail;
memset(key[i], 0, NAME_MAX_LEN);
strcpy(key[i], key_path);
if (key_path[strlen(key_path) - 1] != '\/')
key[i][strlen(key_path)] = '/';
}

strcat(key[0], "rsa2048_0.pem");
strcat(key[1], "rsa2048_1.pem");

fd = open(hash_data, O_CREAT | O_TRUNC | O_WRONLY, 0644); //打开哈希文件
if (fd == 0) {
printf("error:could create '%s'\n", hash_data);
return 0;
}
if (write(fd, data, hash_data_len) != hash_data_len)            //哈希文件,写入16进制数据
goto fail;
// unlink(hash_data);     //删除哈希文件
close(fd);
一般无上面操作,直接读取16进制文件
input_data = load_file(img, &img_len);
if (input_data == 0) {
printf("error:could not load img\n");
return 0;
}
printf("img_len = %d\n", img_len);

calcSignature(data, hash_data_len, signature, key[0]);   //签名运算

printf("signature: ");
for(i=0;i<256;i++)
printf("x",signature[i]);    //打印签名
printf("\n");

fd = open(hash_sign, O_CREAT | O_TRUNC | O_WRONLY, 0644); //打开签名文件
if (fd == 0) {
printf("error:could create '%s'\n", hash_sign);
return 0;
}
if (write(fd, signature, 256) != 256)  //写入签名结果
goto fail;
// unlink(hash_sign);  //删除签名文件
close(fd);
printf("---------------------------------------------------------------\n");
return 1;

fail:
printf("sign failed!!!\n");
for (i = 0; i < 2; i++) {
if (key[i] != 0)
free(key[i]);
}

return 0;
}

int main(int argc, char **argv)
{
if (argc != 4) {
usage();
return 0;
}
char *cmd1 = argv[1]; //hash_data.bin
char *cmd2 = argv[2]; //hash_sign.bin
char *cmd3 = argv[3]; //key documount
sprd_signimg(cmd1, cmd2, cmd3);
}

.sh脚本文件
#!/bin/sh

HOST_OUT=$CURPATH/out/host/linux-x86/bin   //可执行模块路径
CFGPATH=$(pwd)        //当前路径
HASH_DATA=$(pwd)/hash_data.bin 
HASH_DATA_SIGNED=$(pwd)/hash_sign.bin

doSign()
{
    $HOST_OUT/sign $HASH_DATA $HASH_DATA_SIGNED $CFGPATH
}

doSign "$@"
    -------------------------------------------------------------------------------------------------
10.RSA公钥验签
    //使用RSA密钥验证,实际上使用其中的公钥解密
    $ openssl rsautl -verify -in sign.txt -inkey RSA.pem -out replain.txt
     //使用RSA公钥验证
    $ openssl rsautl -verify -in sign.txt -inkey pub.pem -pubin -out replain.txt
    //比较原始文件和签名解密后文件
    $ diff plain.txt replain.txt
    注:相同明文,相同密钥加密/签名后的密文结果不一样?
          是因为填充模式中要填充随机数,导致每次加密结果不同。
          相同明文,相同密钥,默认的-pkcs填充格式每次签名结果是一样的。
-----------------------------------------------------------------------------------------------------------------
附:rsa1024密钥各参数
Private-Key: (1024 bit) (大端模式)
modulus:
   00:aa:cd:56:35:d5:00:2d:12:dd:cd:10:85:39:0c:
    f8:61:70:08:5d:a1:a0:d3:6b:50:34:85:b8:db:19:
    f5:0a:b5:29:f6:0d:f8:e4:1c:a8:b4:24:bf:ac:13:
    c3:c3:47:75:a2:23:74:56:4d:b9:b1:50:e7:5e:21:
    82:c3:80:39:c9:6e:9d:1f:2c:33:59:39:cd:f3:69:
    dc:11:84:a3:5c:4e:c8:3a:ca:e7:a2:6f:68:39:ea:
    b9:ad:86:c5:de:0c:6c:a4:8a:0c:aa:d6:29:f8:20:
    94:84:91:0a:2c:98:65:05:c6:d1:d4:68:db:5a:01:
    67:5a:66:d8:4e:a4:ce:2f:bd
publicExponent: 65537 (0x10001)
privateExponent:
   00:8d:0e:bf:9f:fd:a5:03:94:8d:31:09:ef:bc:4a:
    05:e7:12:8b:16:28:a1:95:79:0e:e8:11:77:b5:1b:
    1e:d0:15:05:ee:7b:63:8d:a0:4d:83:58:c6:22:ea:
    bf:c5:ca:82:4f:c1:50:16:e6:61:f1:1a:8b:b9:a5:
    9b:44:b1:e5:06:28:72:43:61:32:5e:47:bc:a8:09:
    06:62:90:7e:81:d4:65:32:1e:ba:34:5a:74:39:45:
    f1:db:64:69:7c:c0:e5:57:73:64:a7:ca:10:51:77:
    20:43:bb:6d:ef:10:13:93:e7:39:9f:47:2d:9d:f4:
    d9:4c:8a:23:c1:62:00:c9:01
prime1:
    00:d9:df:2e:58:91:eb:34:57:e3:c3:36:b7:56:eb:
    4a:6d:92:82:8c:4f:c9:97:54:2f:ec:f6:18:95:93:
    12:4e:25:81:94:6d:8c:46:bf:e9:19:c3:1a:0a:b2:
    2e:94:95:a6:51:57:7b:0e:1c:e9:9a:5d:a0:7b:3f:
    61:3a:60:cb:ed
prime2:
   00:c8:b1:65:dd:89:40:cb:31:af:e4:2d:fd:af:b5:
    c0:2b:e8:a1:33:6d:d9:9d:dc:35:75:43:87:36:fd:
    05:66:10:af:3e:84:99:1b:a5:2f:36:1b:d0:24:98:
    fc:e8:75:77:a9:a1:bf:1e:67:c3:6d:b8:58:ca:47:
    59:44:80:99:11
exponent1:
    63:a9:97:0e:c6:f9:1b:c1:94:9b:a8:fc:e7:12:cc:
    c2:20:c1:fd:23:46:69:26:06:a2:53:d4:dd:1f:20:
    c1:84:a0:a8:e0:0f:ca:11:61:b4:fa:2d:80:75:0f:
    9f:c2:71:09:46:86:30:e7:82:e8:ad:29:8b:17:6c:
    07:83:5d:e5
exponent2:
    00:89:cc:bc:bb:e3:4d:18:f7:d1:e4:e3:eb:47:65:
    8d:40:d8:e7:2e:8f:e3:97:2f:a7:89:0f:c7:dc:ea:
    d8:75:1f:49:a4:ac:99:10:51:58:5c:57:b6:90:1a:
    77:b5:09:4b:13:af:5a:b1:fe:df:42:0c:0c:f3:3f:
    10:3d:27:eb:71
coefficient:
    00:96:02:a5:9d:e3:c1:77:89:2b:6a:71:44:51:9a:
    ad:57:b1:65:c6:a9:45:21:c3:7b:66:e6:da:18:ad:
    64:ff:29:a8:50:a0:3e:1e:1e:e9:7a:1c:bb:ec:a6:
    ef:d3:23:8b:54:43:5a:e3:75:c8:9e:ba:33:27:a5:
    9e:eb:36:34:d4
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCqzVY11QAtEt3NEIU5DPhhcAhdoaDTa1A0hbjbGfUKtSn2Dfjk
HKi0JL+sE8PDR3WiI3RWTbmxUOdeIYLDgDnJbp0fLDNZOc3zadwRhKNcTsg6yuei
b2g56rmthsXeDGykigyq1in4IJSEkQosmGUFxtHUaNtaAWdaZthOpM4vvQIDAQAB
AoGBAI0Ov5/9pQOUjTEJ77xKBecSixYooZV5DugRd7UbHtAVBe57Y42gTYNYxiLq
v8XKgk/BUBbmYfEai7mlm0Sx5QYockNhMl5HvKgJBmKQfoHUZTIeujRadDlF8dtk
aXzA5VdzZKfKEFF3IEO7be8QE5PnOZ9HLZ302UyKI8FiAMkBAkEA2d8uWJHrNFfj
wza3VutKbZKCjE/Jl1Qv7PYYlZMSTiWBlG2MRr/pGcMaCrIulJWmUVd7Dhzpml2g
ez9hOmDL7QJBAMixZd2JQMsxr+Qt/a+1wCvooTNt2Z3cNXVDhzb9BWYQrz6EmRul
LzYb0CSY/Oh1d6mhvx5nw224WMpHWUSAmRECQGOplw7G+RvBlJuo/OcSzMIgwf0j
RmkmBqJT1N0fIMGEoKjgD8oRYbT6LYB1D5/CcQlGhjDnguitKYsXbAeDXeUCQQCJ
zLy7400Y99Hk4+tHZY1A2Ocuj+OXL6eJD8fc6th1H0mkrJkQUVhcV7aQGne1CUsT
r1qx/t9CDAzzPxA9J+txAkEAlgKlnePBd4kranFEUZqtV7FlxqlFIcN7ZubaGK1k
/ymoUKA+Hh7pehy77Kbv0yOLVENa43XInrozJ6We6zY01A==
-----END RSA PRIVATE KEY-----
参考:
1.http://blog.sina.com.cn/s/blog_4fcd1ea30100yh4s.html
2.http://www.qmailer.net/archives/216.html
3.https://www.cnblogs.com/gordon0918/p/5363466.html

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有