<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ssl &#8211; 编程技术记录</title>
	<atom:link href="https://blog.z6z8.cn/tag/ssl/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.z6z8.cn</link>
	<description>世界你好!</description>
	<lastBuildDate>Thu, 21 Nov 2019 02:41:47 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>SSL EVP框架：AES加密</title>
		<link>https://blog.z6z8.cn/2019/11/21/ssl-evp%e6%a1%86%e6%9e%b6%ef%bc%9aaes%e5%8a%a0%e5%af%86/</link>
					<comments>https://blog.z6z8.cn/2019/11/21/ssl-evp%e6%a1%86%e6%9e%b6%ef%bc%9aaes%e5%8a%a0%e5%af%86/#respond</comments>
		
		<dc:creator><![CDATA[holdsky]]></dc:creator>
		<pubDate>Thu, 21 Nov 2019 02:41:47 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[代码片段]]></category>
		<category><![CDATA[AES]]></category>
		<category><![CDATA[GMSSL]]></category>
		<category><![CDATA[ssl]]></category>
		<guid isPermaLink="false">http://blog.z6z8.cn/?p=581</guid>

					<description><![CDATA[AES加密几个要点 对称加密(Symmetry Crypto) 加密和解密的钥匙是同一把----加密方和解密方 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>AES加密几个要点</h1>
<ul>
<li>
<p>对称加密(Symmetry Crypto)<br />
加密和解密的钥匙是同一把----加密方和解密方拥有相同的密钥（音yue，四声）。</p>
</li>
<li>
<p>密钥(key)<br />
任意数据（不一定非得字符串），长度常见为128比特、192比特、256比特，也有支持512比特的算法库</p>
</li>
<li>
<p>初始化向量(IV)<br />
这不是AES算法标准强制要求的，是一种增加AES破解难度的手段。IV和密钥共同参与加密和解密运算。IV长度固定为128比特。</p>
</li>
<li>
<p>加密块(block)<br />
每次加密的块长度都是128比特；输入和输出长度相同，考虑补全模式的情况下，输出的最大长度 = 输入长度+128比特</p>
</li>
<li>
<p>加密模式<br />
是指当需要加密的源数据长度大于128比特时，加密块和加密块之间的运算模式。<br />
常见的有 CBC密码分组链接模式、ECB电码本模式（不推荐）、CTR计算器模式、CFB密码反馈模式、OFB输出反馈模式。</p>
</li>
<li>
<p>补全模式模式（padding）<br />
因为AES一个加密块为16字节，当源数据的最后一个块不足16字节时，需要手动补全为16字节。</p>
</li>
</ul>
<p>一般使用PKCS7模式，手动补全N个N，N为不足的字节数。</p>
<pre><code>例如，最后一个块为 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x10
需要补6个字节，那么就是6个6
 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x10 0x06 0x06 0x06 0x06 0x06 0x06</code></pre>
<h1>EVP AES 加密</h1>
<pre><code class="language-cpp">
#include "openssl/crypto.h"
#include "openssl/aes.h"
#include "openssl/evp.h"

//引入c++的string，作为buffer使用
#include &lt;string&gt;

//std::string 作为返回值其实可以右值优化的。
std::string encrypt(std::string &amp;data , std::string &amp;key ,std::string &amp;iv)
{
     //这里应该做必要的参数校验，如检查key和iv长度
    //指定算法模式
    EVP_CIPHER *ciper = NULL;
    switch (data.size())
    {
        case 128 / 8: ciper =  EVP_aes_128_cbc();break;
        case 192 / 8: ciper =  EVP_aes_192_cbc();break;
        case 256 / 8: ciper =  EVP_aes_256_cbc();break;
        default:return "需要做一些错误处理";
    }

    //初始化ctx
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    //指定加密算法及key和iv
    int ret = EVP_EncryptInit_ex(ctx, ciper, NULL, (unsigned char *)key.c_str(),  (unsigned char *)iv.c_str());
    if(ret != 1)
    {//EVP_EncryptInit_ex failed
        EVP_CIPHER_CTX_free(ctx);
        return "需要做一些错误处理";
    }

    // 设置padding EVP框架默认使用的就是PKCS7
    EVP_CIPHER_CTX_set_padding(ctx, 1);

   std::string buffer;
   buffer.append(0,AES_BLOCK_SIZE + data.size());

    int mlen = 0;
    //进行加密操作
    ret = EVP_EncryptUpdate(ctx, (unsigned char *)buffer.c_str(), &amp;mlen, (unsigned char *)data.c_str(),(int)buffer.size());
    if(ret != 1)
    {
        EVP_CIPHER_CTX_free(ctx);
        return "需要做一些错误处理";
    }

    int flen = 0;
    //结束加密操作
    ret = EVP_EncryptFinal_ex(ctx, (unsigned char *)buffer.c_str()+mlen, &amp;flen);
    if(ret != 1)
    {
        EVP_CIPHER_CTX_free(ctx);
        return "需要做一些错误处理";
    }
    EVP_CIPHER_CTX_free(ctx);
    buffer.resize(mlen + flen);
    return buffer;
}
</code></pre>
<h1>EVP AES 解密</h1>
<pre><code class="language-cpp">
std::string decrypt(std::string &amp;data , std::string &amp;key ,std::string &amp;iv)
{
   //这里应该做必要的参数校验，如检查key和iv长度
    //指定算法模式
    EVP_CIPHER *ciper = NULL;
    switch (data.size())
    {
        case 128 / 8: ciper =  EVP_aes_128_cbc();break;
        case 192 / 8: ciper =  EVP_aes_192_cbc();break;
        case 256 / 8: ciper =  EVP_aes_256_cbc();break;
        default:return "需要做一些错误处理";
    }

    //初始化ctx
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    //指定加密算法及key和iv
    int ret = EVP_DecryptInit_ex(ctx, ciper, NULL,  (unsigned char *)key.c_str(),  (unsigned char *)iv.c_str());
    if(ret != 1)
    {//EVP_EncryptInit_ex failed
        EVP_CIPHER_CTX_free(ctx);
        return  "需要做一些错误处理";
    }

    // 设置padding功能 EVP框架默认使用的就是PKCS7
    EVP_CIPHER_CTX_set_padding(ctx, 1);

    std::string buffer;
    buffer.append(0,data.size());

    int mlen = 0;
    //进行解密操作
    ret = EVP_DecryptUpdate(ctx,  (unsigned char *)buffer.c_str(), &amp;mlen,  (unsigned char *)data.c_str(),(int) data.size());
    if(ret != 1)
    {
        EVP_CIPHER_CTX_free(ctx);
        return  "需要做一些错误处理";
    }

    int flen = 0;
    //结束解密操作
    ret = EVP_DecryptFinal_ex(ctx, (unsigned char *)buffer.c_str()+mlen, &amp;flen);
    if(ret != 1)
    {
        EVP_CIPHER_CTX_free(ctx);
        return  "需要做一些错误处理";
    }

    EVP_CIPHER_CTX_free(ctx);
    buffer.resize(mlen + flen);
    return buffer;
}</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.z6z8.cn/2019/11/21/ssl-evp%e6%a1%86%e6%9e%b6%ef%bc%9aaes%e5%8a%a0%e5%af%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>nginx 配置SSL证书</title>
		<link>https://blog.z6z8.cn/2019/09/23/nginx-%e9%85%8d%e7%bd%aessl%e8%af%81%e4%b9%a6/</link>
		
		<dc:creator><![CDATA[holdsky]]></dc:creator>
		<pubDate>Mon, 23 Sep 2019 05:47:42 +0000</pubDate>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[ssl]]></category>
		<guid isPermaLink="false">http://blog.z6z8.cn/?p=376</guid>

					<description><![CDATA[支持SSL/TLS 在nginx的虚拟主机配置文件中添加 server { # http配置 listen 8 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>支持SSL/TLS</h1>
<p>在nginx的虚拟主机配置文件中添加</p>
<pre><code>server {
    # http配置
    listen 80;
    listen [::]:80;
    server_name  test.abc.com;

    #######  SSL配置 #########
    listen 443 ssl;
    listen [::]:443 ssl;

    #解决The plain HTTP request was sent to HTTPS port 
    # https://www.centos.bz/2018/01/nginx%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3the-plain-http-request-was-sent-to-https-port%E9%94%99%E8%AF%AF/
    ssl off;

    #ssl 会话超时
    ssl_session_timeout  5m;

    #支持的SSL/TLS协议版本 ，如SSLv2 SSLv3 TLSv1;
    ssl_protocols  SSLv3 TLSv1;
    #支持的协商算法
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers   on;

    # SSL证书位置
    ssl_certificate        /xxxx/xxxx/123.crt;
    ssl_certificate_key    /xxxx/xxxx/456.key;
   ################

   其他配置略
   .....

}
</code></pre>
<h1>自动转发HTTP到HTTPS</h1>
<p>原理是rerwite规则，重定向到https，所以需要创建两个虚拟主机，一个http，一个https</p>
<p>配置如下</p>
<pre><code>server {
    listen 80;
    listen [::]:80;
    server_name test.abc.com;
    #转发到https://xxxx
    rewrite ^(.*) https://$server_name$1 permanent;
}

server {
    server_name  test.abc.com;

    #以下内容不变

    #######  SSL配置 #########
    listen 443 ssl;
    listen [::]:443 ssl;

    #解决The plain HTTP request was sent to HTTPS port 
    # https://www.centos.bz/2018/01/nginx%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3the-plain-http-request-was-sent-to-https-port%E9%94%99%E8%AF%AF/
    ssl off;

    #ssl 会话超时
    ssl_session_timeout  5m;

    #支持的SSL/TLS协议版本 ，如SSLv2 SSLv3 TLSv1;
    ssl_protocols  SSLv3 TLSv1;
    #支持的协商算法
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers   on;

    # SSL证书位置
    ssl_certificate        /xxxx/xxxx/123.crt;
    ssl_certificate_key    /xxxx/xxxx/456.key;
   ################

   其他配置略
   .....

}
</code></pre>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
