Openssl - Across Platform(iOS)

一、Overview

二、Environment Installation

三、Symetric & Asymetric Algorithm

3.1 Symetric

3.2 Asymetric

Generate encrypt key by below funs in OpenSSL

int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
int DSA_generate_key(DSA *dsa);
int EC_KEY_generate_key(EC_KEY *eckey);
int DH_generate_key(DH *dh);

3.2.1 ECC
  • cmd
// Gen private key(.pem格式)
openssl ecparam -name prime256v1 -genkey -noout -out private.key
// Retrieve pub key(.pem格式)
openssl ec -in private.key -pubout -out public.key
  • Implementation

四、Entities

  • EVP_PKEY
struct evp_pkey_st
    {
    int type;
    int save_type;
    int references;
    const EVP_PKEY_ASN1_METHOD *ameth;
    ENGINE *engine;
    union   {
        char *ptr;
#ifndef OPENSSL_NO_RSA
        struct rsa_st *rsa; /* RSA */
#endif
#ifndef OPENSSL_NO_DSA
        struct dsa_st *dsa; /* DSA */
#endif
#ifndef OPENSSL_NO_DH
        struct dh_st *dh;   /* DH */
#endif
#ifndef OPENSSL_NO_EC
        struct ec_key_st *ec;   /* ECC */
#endif
        } pkey;
    int save_parameters;
    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
    } /* EV

OpenSSL之PKey的EVP封装


  • ECC结构在ecc.h
struct ec_key_st {
    EC_GROUP *group;
    EC_POINT *pub_key;
    BIGNUM   *priv_key;
} /* EC_KEY */;

五、Usage

  • AES(Encrypt | Decrypt)
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<openssl/evp.h>
#include<openssl/x509.h>
#pragma comment(lib, "libeay32.lib") 
#define BUFSIZE 128
void tEVP_Encrpyt()
{
unsigned char key[EVP_MAX_KEY_LENGTH]; //密钥
unsigned char iv[EVP_MAX_IV_LENGTH]; // 初始化向量
EVP_CIPHER_CTX ctx; 
//EVP算法上下文
int outl;
int outltmp;
int rv;
int I;
unsigned char out[BUFSIZE]; // 输出密文缓冲区
unsigned char in[BUFSIZE];
const unsigned char *buffer;
buffer=(unsigned char *)malloc(sizeof(in));
memset(in,NULL,sizeof(in));
memset(out,NULL,sizeof(out));
//unsigned char *out;
printf("请输入明文");
scanf("%s",in);
//const unsigned char *msg="Hello OpenSSL";
//设置key 和iv (可采用随机数,也可以由用户输入)
/*for(i=0;i<24;i++)
{
key[i]=I;
}*/
printf("请输入密钥:");
scanf("%s",key);
for(i=0;i<8;i++)
{
iv[i]=I;
}
//初始化密码算法结构体
EVP_CIPHER_CTX_init(&ctx);
//设置算法和密钥以及初始化向量
//rv= EVP_EncryptInit_ex(&ctx,EVP_aes_128_cbc(),NULL,key,iv);
rv= EVP_DecryptInit_ex(&ctx,EVP_aes_128_cbc(),NULL,key,iv);
if(rv!=1)
{
printf("Err\n");
return ;
}
//数据加密
//rv=EVP_EncryptUpdate(&ctx,out,&outl,in,strlen(in));
rv=EVP_DecryptUpdate(&ctx,out,&outl,in,strlen(in));
if(rv!=1)
{
printf("Err\n");
return;
}
//结束数据加密,把剩余数据输出
//rv=EVP_EncryptFinal_ex(&ctx,out+outl,&outltmp);
rv=EVP_DecryptFinal_ex(&ctx,out+outl,&outltmp);
if(rv!=1)
{
printf("Err\n");
return;
}
outl=outl+outltmp;
printf("原文为:%s\n",in);
//打印输出密文
printf("密文长度:%d\n密文数据:\n",outl);

for(i=0;i<outl;i++)
{
printf("0X%02x ",out[I]);
}
}
  • ECC
    1.Generate key pair
groupt -> ec_key -> evp_ec_key
  • ECDH

1.Generate Shared secret (using private key and other Public key)

 #include <openssl/evp.h>

 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
 int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
                                 int validate_peer);
 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);

2.get private key

3.get public key

如何在OpenSSL的EVP_PKEY结构中访问原始ECDH公钥,私钥和参数?

  • CA校验子证书

X509_STORE 与 X509_STORE_CTX的用法区别


六、Appendix

【1】 OpenSSL
【2】X509_STORE 与 X509_STORE_CTX的用法区别

6.1 OpenSSL制作证书

OpenSSL制作证书

生成证书的步骤与原理

要理解创建证书的每一步操作必须先理解创建证书的流程和每一步的含义,生成证书的标准流程如下:

  1. 生成自己的私钥文件(.key)
  2. 基于私钥生成证书请求文件(.csr)
  3. 将证书请求文件(.csr)提交给证书颁发结构(CA),CA会对提交的证书请求中的所有信息生成一个摘要,然后使用CA跟证书对应的私钥进行加密,这就是所谓的“签名”操作,完成签名后就会得到真正的签发证书(.cer或.crt)
  4. 用户拿到签发后的证书,可能需要导入到自己的密钥库中,如Java的keystore,或根据需要再进行各种格式转换(.pen .p12 .jks等等)

<font color=red>注意:</font>
1.第1/2两步可以通过一个命令合并完成。
2.第3步向公认可信的CA机构申请证书是<font color=red>线上线下</font>都要进行的一系列流程。申请的公司或组织还要提交各种资质和证明,与企业申请某种执照或办理某种手续性质类似,但企业最终拿到的就是一个CA签名的证书文件。所以,对于企业内部应用来说,完全可以自己创建自己的根证书,自己给自己签发证书,然后通过域控手段强制用户浏览器接受来自相应CA签发的证书。
3.再次解释下“签名”的含义,这个概念很关键。在CA签发的证书中,包含申请者的公钥在内,几乎所有的数据都是明文的,也都是申请者自己提供的(当然CA需要审核),签发的证书唯一多出来的信息就是基于申请者提供的所有信息生成了一份摘要,然后用CA自己的私钥对摘要进行了加密,这段加密后的密文被称之为“签名”,这部分数据是返还的签发证书(.cer或.crt)中多出来的关键数据。下图是CA签发证书的原理:
[图片上传失败...(image-5f4ce5-1696863276635)]

汇总所有的情况来看,生成证书不外乎三种情形:

  • 标准CA签发流程
  • 生成自签名证书
  • 生成私有CA签发的证书

对于绝大多数的开发者而言,需要使用的其实是后两种:自签名证书和私有CA签发的证书。对这两种证书的差异,笔者现在理解的还不够透彻,需要进一步研究。网上的说法是:自签名证书无法被吊销,私有CA签发的证书可以被吊销。从它们各自的命令行工具上看,后者确实有一个撤销操作openssl ca -revoke。此外,生成两种证书的命令也是不一样的。

针对私有CA签发的证书,网上有如下的建议:

  • 如果你的规划需要创建多个证书,那么使用私有CA的方法比较合适,因为只要给所有的客户端都安装了CA的证书,那么以该证书签名过的证书,客户端都是信任的,也就是安装一次就够了。

  • 如果你直接用自签名证书,你需要给所有的客户端安装该证书才会被信任。如果你需要第二个证书,则还得挨个给所有的客户端安装证书2才会被信任。

标准的CA签发流程

对应文章开头提及的证书生成流程,标准CA签发流程中的第三步是需要CA机构操作的,我们会解释CA机构要做的工作。

1.创建要是

openssl genrsa -out my.key 2048

2.基于私钥创建证书签名请求(.csr)

openssl req -new -key my.key -out my.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"

这一操作有一个关键点:除了在请求中提交了申请人的一些组织信息之外,最重要的就是把上次生成的私钥作为参数传给命令行,这是因为命令行工具能根据私钥算出对应的公钥,
公钥是未来证书的核心组成部分。

3.(可选)直接同时生成私钥和证书签名请求
上述两个操作是可以通过一条命令完成的,即同时生成my.key和my.csr两个文件:

openssl req -new -newkey rsa:2048 -nodes -keyout my.key -out my.csr -subj "/C=CN/ST=shanghai/O=example/OU=it/CN=domain1/CN=domain2"

<font color=red>两个关键参数:</font>

  • -newkey rsa:2048 -> 生成一个新的证书签名请求,同时生成一个2048位的RSA私钥
  • -nodes -> 不对新私钥加密

4.将证书申请请求(.csr)提交给CA认证机构申请证书(.crt)
如上所述,此为事物性的审批操作,无本地命令操作。但是在CA机构那里,实行人员一定会使用CA自己的密钥对CSR进行签名操作,这一步操作与我们将在第4节介绍的使用私钥CA证书对应的私钥进行签名性质上是一样的。

简单将:从CSR到CRT,就是一个签名过程,这个过程需要用签发方的私钥。走标准CA签发流程,是CA机构来操作,用的是他的根证书对应的私钥来签名;走自签名证书或私有CA证书的流程,用的就是自己的私钥。

5.CA机构生成CA证书链
绝大多数情况下,CA机构返还不是一个单一的证书,而是一个证书链。关于证书链,我们会单独起一篇文章进行解释。这里先简单介绍一下:通常机构颁发的证书中会包含完整的证书链,可以直接使用。如果没有包含完整的证书链,浏览器通常会自动下载并补全上级证书,安装完成后不再显示安全警告。在颁发的证书中都会有它的上级和下级证书的相关信息。也包含下载地址,所以浏览器是可以自动下载补全的。但很多企业内网往往不允许连接到互联网,无法补全证书链。所以最好的办法是先补全证书链,再部署的网站上。
一张标准的证书,都会包含自己的颁发者名称,以及颁发者机构访问信息:Authority info Access,其中就会有颁发者CA证书的下载地址。
[图片上传失败...(image-fa7fdb-1696863276635)]

通过这个URL,我们可以获得这个证书的颁发者证书,即中间证书。Windows、IOS、MAC都支持这种证书获取方式。

生成自签名证书

1.创建私钥(.key)

openssl genrsa -out my.key 2048

2.基于私钥(.key)创建证书签名请求(.csr)

openssl req -new -key my.key -out my.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"

3.(可选)直接同时生成私钥(.key)和证书签名请求(.csr)

openssl req -new -newkey rsa:2048 -nodes -keyout my.key -out my.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"

4.使用自己的私钥(.key)签署自己的证书签名请求(.csr),生成自签名证书(.crt)

openssl x509 -req -in my.csr -out my.crt -signkey my.key -days 3650

对于这条命令,要注意一下几点:
这个命令是openssl x509,-req是参数,和前面生成证书签名请求的openssl req命令不同。-signkey my.key配置清晰地表明使用自己的私钥进行签名。

5.(可选)直接同时生成私钥(.key)和自签名证书(.crt)
上述三步骤也可以通过一个命令一次完成:

openssl req -x509 -newkey rsa:2048 -nodes -keyout my.key -out my.crt -days 3650 -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"

这个命令要和3.3.3仔细区分开,3.3.3的命令是openssl req -new -newkey ...,这里的openssl req -x509 -newkey ...,关键的区别就是把-new改成了-x509,-x509参数指明要输出的是一个证书,所以我们out文件是.crt后缀,而如果没有-x509,生成是证书签名请求,out文件就得是.csr后缀。

生成私有CA签发的证书

与生成自签名证书不同地方在于,生成自签名证书场景下只有一个参与方,请求证书和签发证书都是自己,而生成私有CA证书的场景里开始涉及两个角色了:
签发证书的一方:CA(主要牵涉的是CA私钥和根证书)
请求签发证书的一方:如服务器
为了便于区别,我们把它相关的文件分别用ca和server加以区别。

1.生成CA私钥(ca.key)和CA自签名证书(ca.crt)
为了简化操作,我们会仿照3.3.5的操作,一步生成CA私钥和CA自签名证书

openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -days 3650 -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"

可以看到私有CA证书其实就是一个普通的自签名证书。

2.生成Server端私钥(server.key)和证书签名请求(server.csr)

openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"

3.使用CA证书(ca.crt)与密钥(ca.key)签署服务器的证书签名请求(server.csr),生成私有CA签名的服务器证书(server.crt)
接下来关键一步:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650

对比3.4节生成自签名的命令行,我们可以看到,这里没有了-signkey my.key参数,而是改为了-CA ca.crt -CAkey ca.key,目前让我困惑的是为什么还需要使用ca.crt文件呢? 是要生成证书链么?需验证。
<font size=3 color=red>关于-CAcreateserial:</font>
当签署证书是,CA需要为每个证书生成一个唯一的序列号,由于每个证书的序列号对于每个颁发者都必须是唯一的,因此颁发者需要跟踪它以前使用过哪些序列号。以确保它不会重复使用任何序列号。
OpenSSL提供了一种使用序列号文件进行跟踪的简单方法。当你指定-CAcreateserial时,它会将序列号01或一个随机数分配给签名证书,然后创建此序列号文件。在未来的签名操作中,应该使用-CAserial和改改文件的名称,而不是-CAcreateserial,并且OpenSSL将为每个签名的证书增加该文件中的值。这样,你可以用一个颁发者证书签署一堆证书,并且他们所有序列号都是唯一的。
最后,我们还可以使用如下命令来验证server.crt是否真得是由ca签发的。

openssl verify -CAfile ca.crt server.crt

如果显示OK,就是验证成功了。

Others

  • cfssl制作证书
  • 其他工具制作证书

Appendix

[附录一:openssl req 命令参数说明]

-days <n>
指定证书有效期,默认是30天,与-x509 选项一起使用
-newkey rsa:2048
生成一个新的证书申请,同时生成一个2048位的RSA 私钥
-keyout <keyfile>
新私钥更马人的文件
- nodes
不对新私钥加密
-key <keyfile>
读取指定的私钥文件。
-text
同时打印纯文本版本和编码版本信息
-noout
不打印编码后版本(BASE64编码)
-new
生成一个新的证书申请,会提示用户锱入相关宇段的值,如果没有-key选项,会使用指定配置文件中的信息生成一个新的RSA私钥。
-×509
输出自签名的证书,而不是请求一个证书,通常用于生成测试证书或自签名的根证书
-subj <arg>
申请人信息,格式是 /C=CN/O=Corp/.../CN=www.ez.com,可以使用\转义,不会跳过空格。
-[digets] 指定签署请求时使用的信息摘要算法,如:-md5、-sha1、-sha256
时
A
-/CN-ww.ez.com,可以使用、转义,,不会躁

[附录二:openssl req的-subj参数说明]

/C=Country 国家
/ST= State or Province 省
/L= Location or City 城市
/O= Organization 组织或企业
/OU= Organization Unit 部门
/CN= Common Name 域名或IP
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,018评论 0 4
  • 公元:2019年11月28日19时42分农历:二零一九年 十一月 初三日 戌时干支:己亥乙亥己巳甲戌当月节气:立冬...
    石放阅读 6,864评论 0 2