blog / 2020 /05 /29 /encrypt.html
User Mayx
update
a8648b2
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Begin Jekyll SEO tag v2.8.0 -->
<title>写一个加密传输的Demo | Mayx的博客</title>
<meta name="generator" content="Jekyll v3.9.5" />
<meta property="og:title" content="写一个加密传输的Demo" />
<meta name="author" content="mayx" />
<meta property="og:locale" content="zh_CN" />
<meta name="description" content="非专业密码学,仅供娱乐!" />
<meta property="og:description" content="非专业密码学,仅供娱乐!" />
<meta property="og:site_name" content="Mayx的博客" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2020-05-29T00:00:00+08:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="写一个加密传输的Demo" />
<meta name="google-site-verification" content="huTYdEesm8NaFymixMNqflyCp6Jfvd615j5Wq1i2PHc" />
<meta name="msvalidate.01" content="0ADFCE64B3557DC4DC5F2DC224C5FDDD" />
<meta name="yandex-verification" content="fc0e535abed800be" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"mayx"},"dateModified":"2020-05-29T00:00:00+08:00","datePublished":"2020-05-29T00:00:00+08:00","description":"非专业密码学,仅供娱乐!","headline":"写一个加密传输的Demo","mainEntityOfPage":{"@type":"WebPage","@id":"/2020/05/29/encrypt.html"},"publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"https://avatars0.githubusercontent.com/u/17966333"},"name":"mayx"},"url":"/2020/05/29/encrypt.html"}</script>
<!-- End Jekyll SEO tag -->
<link rel="canonical" href="https://mabbs.github.io/2020/05/29/encrypt.html" />
<link type="application/atom+xml" rel="alternate" href="/atom.xml" title="Mayx的博客" />
<link rel="alternate" type="application/rss+xml" title="Mayx的博客(RSS)" href="/rss.xml" />
<link rel="alternate" type="application/json" title="Mayx的博客(JSON Feed)" href="/feed.json" />
<link rel="stylesheet" href="/assets/css/style.css?v=1762336075" />
<!--[if !IE]> -->
<link rel="stylesheet" href="/Live2dHistoire/live2d/css/live2d.css" />
<!-- <![endif]-->
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Mayx的博客" />
<link rel="webmention" href="https://webmention.io/mabbs.github.io/webmention" />
<link rel="pingback" href="https://webmention.io/mabbs.github.io/xmlrpc" />
<link rel="preconnect" href="https://summary.mayx.eu.org" crossorigin="anonymous" />
<link rel="prefetch" href="https://www.blogsclub.org/badge/mabbs.github.io" as="image" />
<link rel="blogroll" type="text/xml" href="/blogroll.opml" />
<link rel="me" href="https://github.com/Mabbs" />
<script src="/assets/js/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script>
var lastUpdated = new Date("Wed, 05 Nov 2025 17:47:55 +0800");
var BlogAPI = "https://summary.mayx.eu.org";
</script>
<script src="/assets/js/main.js"></script>
<!--[if !IE]> -->
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-137710294-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-137710294-1');
</script>
<script src="/assets/js/instant.page.js" type="module"></script>
<!-- <![endif]-->
</head>
<body>
<!--[if !IE]> --><noscript><marquee style="top: -15px; position: relative;"><small>发现当前浏览器没有启用JavaScript,这不影响你的浏览,但可能会有一些功能无法使用……</small></marquee></noscript><!-- <![endif]-->
<!--[if IE]><marquee style="top: -15px; position: relative;"><small>发现当前浏览器为Internet Explorer,这不影响你的浏览,但可能会有一些功能无法使用……</small></marquee><![endif]-->
<div class="wrapper">
<header class="h-card">
<h1><a class="u-url u-uid p-name" rel="me" href="/">Mayx的博客</a></h1>
<img src="https://avatars0.githubusercontent.com/u/17966333" fetchpriority="high" class="u-photo" alt="Logo" style="width: 90%; max-width: 300px; max-height: 300px;" />
<p class="p-note">Mayx's Home Page</p>
<form action="/search.html">
<input type="text" name="keyword" id="search-input-all" placeholder="Search blog posts.." />&#160;<input type="submit" value="搜索" />
</form>
<br />
<p class="view"><a class="u-url" href="/Mabbs/">About me</a></p>
<ul class="downloads">
<li style="width: 270px; border-right: none;"><a href="/MayxBlog.tgz">Download <strong>TGZ File</strong></a></li>
</ul>
</header>
<section class="h-entry">
<small><time class="date dt-published" datetime="2020-05-29T00:00:00+08:00">29 May 2020</time> - 字数统计:4777 - 阅读大约需要16分钟 - Hits: <span id="/2020/05/29/encrypt.html" class="visitors">Loading...</span></small>
<h1 class="p-name">写一个加密传输的Demo</h1>
<p class="view">by <a class="p-author h-card" href="//github.com/Mabbs">mayx</a></p>
<div id="outdate" style="display:none;">
<hr /><p>
这是一篇创建于 <span id="outime"></span> 天前的文章,其中的信息可能已经有所发展或是发生改变。
</p>
</div>
<script>
daysold = Math.floor((new Date().getTime() - new Date("Fri, 29 May 2020 00:00:00 +0800").getTime()) / (24 * 60 * 60 * 1000));
if (daysold > 90) {
document.getElementById("outdate").style.display = "block";
document.getElementById("outime").innerHTML = daysold;
}
</script>
<hr />
<b>AI摘要</b>
<p id="ai-output">这篇文章是一个关于非专业密码学的Python实现示例,作者是为了一个学校工程项目研究通信安全而写的简化的加密传输Demo。主要使用AES用于数据加密,RSA用于加密AES的密钥,以及MD5进行数据校验。作者选择这些技术主要是为了保证通信过程中的安全性,虽然简化了RSA和TLS的握手过程以降低复杂性。传输方式则是通过文件而非TCP或Unix Domain Socket。虽然许多代码是从网上获取的,但文章展示了如何使用Python的Crypto库进行加密和解密操作。</p>
<hr />
<ul><li><a href="#起因">起因</a></li><li><a href="#实现思路">实现思路</a></li><li><a href="#代码">代码</a><ul><li><a href="#serverpy">server.py</a></li><li><a href="#clientpy">client.py</a></li></ul></li><li><a href="#感想">感想</a></li></ul>
<hr />
<main class="post-content e-content" role="main"><p>非专业密码学,仅供娱乐!<!--more--></p>
<h1 id="起因">
<a href="#起因"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 起因
</h1>
<p>最近我们学校搞了一个工程项目,要求是研究关于信息安全等级保护的一些东西,一开始我以为这就是搞个权限啥的,后来发现和云计算一样是个定义,话说我明明是网络工程专业的为啥还要了解信息安全…… </p><p>
当然这个什么等级保护的内容很多,我们不可能全都涉及,所以老师允许我们只选其中的一部分进行研究。我想了想,我之前还想搞什么<a href="/2019/07/02/encmail.html">加密邮件</a>啥的,所以我选了通信安全方面的板块,这样也可以对那个项目有些参考。</p>
<h1 id="实现思路">
<a href="#实现思路"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 实现思路
</h1>
<p>我本来是想按着TLS的标准来写,后来看了看发现那样不太方便,我写Demo也就是玩玩而已,不用费那么大劲。 </p><p>
像正常来说,建立加密通道是要有握手环节的,但是那个实现起来实在是太麻烦,所以想了想就算了。 </p><p>
所以我的实现方式是生成一个随机数,用AES以随机数为密码加密数据,用RSA加密随机数。这样做的主要目的是利用RSA的特性保证传输内容不会被泄露,但是RSA相对来说太慢,所以用了AES来加密数据,这样就能提高传输的效率。 </p><p>
传送方式我之前还想着要不要建一个TCP Socket或者是Unix Domain Socket来传输,但是后来觉得这样太麻烦,不如直接用文件的方式传,这样还简单好理解。 <del>(就是嫌麻烦嘛)</del> </p><p>
另外在通信安全中还有一点是要求校验数据,我想了想就用MD5吧,正常来说得到MD5后还要数字签名啥的,我觉得麻烦也就没搞,所以最终传输的内容就是AES加密后的数据、原数据的MD5(Hash)以及用RSA加密的密钥。 </p><p>
虽然我学Python的时间不长,不过我现在发现Python在做这些事情的时候远比Shell、PHP和JS简单,所以这次的Demo也是用Python实现的。 </p><p>
不过我的Python并不怎么样,所以大多数代码都是从网上Copy的,像Crypto的库我不搜一下肯定是不会用嘛。 </p><p>
既然用到了Crypto库,那么如果有人有兴趣执行下面的代码,自然需要执行一下<code class="language-plaintext highlighter-rouge">pip3 install pycryptodome</code>才可以正常运行啦。</p>
<h1 id="代码">
<a href="#代码"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 代码
</h1>
<h2 id="serverpy">
<a href="#serverpy"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> server.py
</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># -*- coding: utf-8 -*-
</span>
<span class="kn">from</span> <span class="nn">Crypto.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">PKCS1_v1_5</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">import</span> <span class="nn">base64</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="n">private_key</span> <span class="o">=</span> <span class="s">"""-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDfEQ82qUrto7h4BL3TsA/DFXSdM44cbeY4kPccD7gLGhaZRClz
YKIh5zYdfjBGF+0HXfMa1u9b7GNs2AjVIsx8Kx0QLnMfmtkmGWGhOXz/9IDLKJOx
0weKv61gysKItgzVKn2mbLool4R/PQBc3AjDyHw+io1KpVz+3kRTaGs1fQIDAQAB
AoGAWB4kFWLA/6k6OOcemd4mC9mQ7HyuOdrMJDJX+5TWDkSrArajbTmSMrRkczgj
F71h3BQn8cVQXs695ARfUNrjTbi2Y0LjN7ScK7ExzTLdoMEFw5JsHggJZ0zBQY6w
mwOdGfqzA6tZPXgkn+jqEha+CD6GrwnTM1oDGJC/aKG2OmECQQDkO9IhUhFc/PSU
0zvGE6AOcqk5wlOuvMg+oAFHJHJZ9XW7+X/Nx0ZoVDFq/cZQj+46t+fiwUwhdW7l
IfCvNGKFAkEA+jRQmWGKrbf1ns4S0SezJvysd5O6otRGJXr+Ex2uDhc39ZTeUsyg
kjrLhp8STLMOmql+8g5fghct17EuCX1EmQJBAJz9BNnEkIrst/OSpH/nyeWGOx6u
q077LaXd+2MLD9kO/O/Se3V5B9YFa4STkJCjoBMloswXd51gIGpdgSeSmd0CQQCL
PrwwcGmWfo+ynqs4PajlpK9zKQMwhYS4bTejedwZOXDKOtx0Ji+i0hfcxwCPMQOK
rZPZsIgUxUOdC508aLvZAkBDkHxunCzDm0w4DdTUN7S9YSpVvQEjK/xUQiWaKV12
8QgskhU2DNdYK2NxifnWrKtx3uQmqMxX5aLuJZ4493yr
-----END RSA PRIVATE KEY-----"""</span>
<span class="c1"># 公钥解密
</span><span class="k">def</span> <span class="nf">rsa_decode</span><span class="p">(</span><span class="n">cipher_text</span><span class="p">,</span> <span class="n">private_key</span><span class="p">):</span>
<span class="n">rsakey</span> <span class="o">=</span> <span class="n">RSA</span><span class="p">.</span><span class="n">importKey</span><span class="p">(</span><span class="n">private_key</span><span class="p">)</span> <span class="c1"># 导入读取到的私钥
</span> <span class="n">cipher</span> <span class="o">=</span> <span class="n">PKCS1_v1_5</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">rsakey</span><span class="p">)</span> <span class="c1"># 生成对象
</span> <span class="c1"># 将密文解密成明文,返回的是一个bytes类型数据,需要自己转换成str
</span> <span class="n">text</span> <span class="o">=</span> <span class="n">cipher</span><span class="p">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">base64</span><span class="p">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">cipher_text</span><span class="p">),</span> <span class="s">"ERROR"</span><span class="p">)</span>
<span class="k">return</span> <span class="n">text</span><span class="p">.</span><span class="n">decode</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">PrpCrypt</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">mode</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">MODE_CBC</span>
<span class="c1"># 解密后,去掉补足的空格用strip() 去掉
</span> <span class="k">def</span> <span class="nf">decrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
<span class="n">cryptor</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">mode</span><span class="p">,</span> <span class="sa">b</span><span class="s">'0000000000000000'</span><span class="p">)</span>
<span class="n">plain_text</span> <span class="o">=</span> <span class="n">cryptor</span><span class="p">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">base64</span><span class="p">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">text</span><span class="p">))</span>
<span class="c1"># return plain_text.rstrip('\0')
</span> <span class="k">return</span> <span class="nb">bytes</span><span class="p">.</span><span class="n">decode</span><span class="p">(</span><span class="n">plain_text</span><span class="p">).</span><span class="n">rstrip</span><span class="p">(</span><span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="p">)</span>
<span class="k">while</span> <span class="ow">not</span> <span class="nb">input</span><span class="p">(</span><span class="s">"按回车读取客户端的信息,输入其他内容结束"</span><span class="p">):</span>
<span class="n">cipher</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">"pipe.txt"</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s">'r'</span><span class="p">)</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">json</span><span class="p">.</span><span class="n">loads</span><span class="p">(</span><span class="n">cipher</span><span class="p">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">cipher</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">rsa_decode</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="s">"key"</span><span class="p">],</span> <span class="n">private_key</span><span class="p">)</span>
<span class="n">aesc</span> <span class="o">=</span> <span class="n">PrpCrypt</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">aesc</span><span class="p">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="s">"message"</span><span class="p">])</span>
<span class="nb">hash</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">md5</span><span class="p">(</span><span class="n">message</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s">'UTF-8'</span><span class="p">)).</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">hash</span> <span class="o">==</span> <span class="n">msg</span><span class="p">[</span><span class="s">"hash"</span><span class="p">]:</span>
<span class="k">print</span><span class="p">(</span><span class="s">"数据校验成功"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">"数据校验失败"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</code></pre></div></div>
<h2 id="clientpy">
<a href="#clientpy"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> client.py
</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># -*- coding: utf-8 -*-
</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">Crypto.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">PKCS1_v1_5</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">import</span> <span class="nn">base64</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="n">public_key</span> <span class="o">=</span> <span class="s">"""-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfEQ82qUrto7h4BL3TsA/DFXSd
M44cbeY4kPccD7gLGhaZRClzYKIh5zYdfjBGF+0HXfMa1u9b7GNs2AjVIsx8Kx0Q
LnMfmtkmGWGhOXz/9IDLKJOx0weKv61gysKItgzVKn2mbLool4R/PQBc3AjDyHw+
io1KpVz+3kRTaGs1fQIDAQAB
-----END PUBLIC KEY-----
"""</span>
<span class="c1"># 公钥加密
</span><span class="k">def</span> <span class="nf">rsa_encode</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">public_key</span><span class="p">):</span>
<span class="n">rsakey</span> <span class="o">=</span> <span class="n">RSA</span><span class="p">.</span><span class="n">importKey</span><span class="p">(</span><span class="n">public_key</span><span class="p">)</span> <span class="c1"># 导入读取到的公钥
</span> <span class="n">cipher</span> <span class="o">=</span> <span class="n">PKCS1_v1_5</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">rsakey</span><span class="p">)</span> <span class="c1"># 生成对象
</span> <span class="c1"># 通过生成的对象加密message明文,注意,在python3中加密的数据必须是bytes类型的数据,不能是str类型的数据
</span> <span class="n">cipher_text</span> <span class="o">=</span> <span class="n">base64</span><span class="p">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">cipher</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">message</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s">"utf-8"</span><span class="p">)))</span>
<span class="c1"># 公钥每次加密的结果不一样跟对数据的padding(填充)有关
</span> <span class="k">return</span> <span class="n">cipher_text</span><span class="p">.</span><span class="n">decode</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">PrpCrypt</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">mode</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">MODE_CBC</span>
<span class="c1"># 加密函数,如果text不足16位就用空格补足为16位,
</span> <span class="c1"># 如果大于16当时不是16的倍数,那就补足为16的倍数。
</span> <span class="k">def</span> <span class="nf">encrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">text</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)</span>
<span class="n">cryptor</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">mode</span><span class="p">,</span> <span class="sa">b</span><span class="s">'0000000000000000'</span><span class="p">)</span>
<span class="c1"># 这里密钥key 长度必须为16(AES-128),
</span> <span class="c1"># 24(AES-192),或者32 (AES-256)Bytes 长度
</span> <span class="c1"># 目前AES-128 足够目前使用
</span> <span class="n">length</span> <span class="o">=</span> <span class="mi">16</span>
<span class="n">count</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="k">if</span> <span class="n">count</span> <span class="o">&lt;</span> <span class="n">length</span><span class="p">:</span>
<span class="n">add</span> <span class="o">=</span> <span class="p">(</span><span class="n">length</span> <span class="o">-</span> <span class="n">count</span><span class="p">)</span>
<span class="c1"># \0 backspace
</span> <span class="c1"># text = text + ('\0' * add)
</span> <span class="n">text</span> <span class="o">=</span> <span class="n">text</span> <span class="o">+</span> <span class="p">(</span><span class="s">'</span><span class="se">\0</span><span class="s">'</span> <span class="o">*</span> <span class="n">add</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">count</span> <span class="o">&gt;</span> <span class="n">length</span><span class="p">:</span>
<span class="n">add</span> <span class="o">=</span> <span class="p">(</span><span class="n">length</span> <span class="o">-</span> <span class="p">(</span><span class="n">count</span> <span class="o">%</span> <span class="n">length</span><span class="p">))</span>
<span class="c1"># text = text + ('\0' * add)
</span> <span class="n">text</span> <span class="o">=</span> <span class="n">text</span> <span class="o">+</span> <span class="p">(</span><span class="s">'</span><span class="se">\0</span><span class="s">'</span> <span class="o">*</span> <span class="n">add</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)</span>
<span class="bp">self</span><span class="p">.</span><span class="n">ciphertext</span> <span class="o">=</span> <span class="n">cryptor</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="c1"># 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
</span> <span class="c1"># 所以这里统一把加密后的字符串转化为16进制字符串
</span> <span class="k">return</span> <span class="n">base64</span><span class="p">.</span><span class="n">b64encode</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">ciphertext</span><span class="p">)</span>
<span class="n">message</span><span class="o">=</span><span class="s">" "</span>
<span class="k">while</span> <span class="n">message</span><span class="p">:</span>
<span class="n">message</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">"请输入需要传输的信息(不输入则结束):"</span><span class="p">)</span>
<span class="nb">hash</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">md5</span><span class="p">(</span><span class="n">message</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s">'UTF-8'</span><span class="p">)).</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="p">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1000000000000000</span><span class="p">,</span><span class="mi">9999999999999999</span><span class="p">))</span>
<span class="n">cipher</span> <span class="o">=</span> <span class="n">rsa_encode</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">public_key</span><span class="p">)</span>
<span class="n">aesc</span> <span class="o">=</span> <span class="n">PrpCrypt</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">data</span><span class="o">=</span><span class="n">json</span><span class="p">.</span><span class="n">dumps</span><span class="p">({</span><span class="s">"message"</span><span class="p">:</span><span class="n">aesc</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">message</span><span class="p">).</span><span class="n">decode</span><span class="p">(</span><span class="s">'utf8'</span><span class="p">),</span><span class="s">"hash"</span><span class="p">:</span><span class="nb">hash</span><span class="p">,</span><span class="s">"key"</span><span class="p">:</span><span class="n">cipher</span><span class="p">})</span>
<span class="k">print</span><span class="p">(</span><span class="n">data</span><span class="p">,</span><span class="nb">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'pipe.txt'</span><span class="p">,</span><span class="s">'w'</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="s">"数据已发出!"</span><span class="p">)</span>
</code></pre></div></div>
<h1 id="感想">
<a href="#感想"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 感想
</h1>
<p>我在写这个代码的时候在网上搜到的资料也真的是算少了,就像我当时打算写加密邮件那时一样,基本上大多数的资料都有问题,像有些代码还是Python2的,还有时候经常遇到什么bytearray、json转换之类乱七八糟的问题。 </p><p>
希望中文网络环境能多一些大家遇到的冷门知识的解决方法啊…… </p><p>
对了,这个代码实际上只有防止中间人窥探信息的能力,并没有防篡改的能力,毕竟没有两端握手,没法做验证,所以这就是一个业余的加密传输代码,仅供参考。</p></main>
<small style="display: block">tags: <a rel="category tag" class="p-category" href="/search.html?keyword=%E5%8A%A0%E5%AF%86"><em>加密</em></a> - <a rel="category tag" class="p-category" href="/search.html?keyword=Demo"><em>Demo</em></a> <span style="float: right;"><a href="https://gitlab.com/mayx/mayx.gitlab.io/tree/master/_posts/2020-05-29-encrypt.md">查看原始文件</a></span></small>
<h4 style="border-bottom: 1px solid #e5e5e5;margin: 2em 0 5px;">推荐文章</h4>
<p id="suggest-container">Loading...</p>
<script>
var suggest = $("#suggest-container");
$.get(BlogAPI + "/suggest?id=/2020/05/29/encrypt.html&update=" + lastUpdated.valueOf(), function (data) {
if (data.length) {
getSearchJSON(function (search) {
suggest.empty();
var searchMap = {};
for (var i = 0; i < search.length; i++) {
searchMap[search[i].url] = search[i];
}
var tooltip = $('<div class="content-tooltip"></div>').appendTo('body').hide();
for (var j = 0; j < data.length; j++) {
var item = searchMap[data[j].id];
if (item) {
var link = $('<a href="' + item.url + '">' + item.title + '</a>');
var contentPreview = item.content.substring(0, 100);
if (item.content.length > 100) {
contentPreview += "……";
}
link.hover(
function(e) {
tooltip.text($(this).data('content'))
.css({
top: e.pageY + 10,
left: e.pageX + 10
})
.show();
},
function() {
tooltip.hide();
}
).mousemove(function(e) {
tooltip.css({
top: e.pageY + 10,
left: e.pageX + 10
});
}).data('content', contentPreview);
suggest.append(link);
suggest.append(' - ' + item.date + '<br />');
}
}
});
} else {
suggest.html("暂无推荐文章……");
}
});
</script>
<br />
<div class="pagination">
<span class="prev">
<a href="/2020/05/20/memory.html">
上一篇:Re:加装内存
</a>
</span>
<br />
<span class="next">
<a href="/2020/06/06/demoscene.html">
下一篇:关于Demoscene的探索
</a>
</span>
</div>
<!--[if !IE]> -->
<link rel="stylesheet" href="/assets/css/gitalk.css">
<script src="/assets/js/gitalk.min.js"></script>
<div id="gitalk-container"></div>
<script>
var gitalk = new Gitalk({
clientID: '36557aec4c3cb04f7ac6',
clientSecret: 'ac32993299751cb5a9ba81cf2b171cca65879cdb',
repo: 'mabbs.github.io',
owner: 'Mabbs',
admin: ['Mabbs'],
id: '/2020/05/29/encrypt', // Ensure uniqueness and length less than 50
distractionFreeMode: false, // Facebook-like distraction free mode
proxy: "https://cors-anywhere.mayx.eu.org/?https://github.com/login/oauth/access_token"
})
gitalk.render('gitalk-container')
</script>
<!-- <![endif]-->
</section>
<!--[if !IE]> -->
<div id="landlord" style="left:5px;bottom:0px;">
<div class="message" style="opacity:0"></div>
<canvas id="live2d" width="500" height="560" class="live2d"></canvas>
<div class="live_talk_input_body">
<form id="live_talk_input_form">
<div class="live_talk_input_name_body" >
<input type="checkbox" id="load_this" />
<input type="hidden" id="post_id" value="/2020/05/29/encrypt.html" />
<label for="load_this">
<span style="font-size: 11px; color: #fff;">&#160;想问这篇文章</span>
</label>
</div>
<div class="live_talk_input_text_body">
<input name="talk" type="text" class="live_talk_talk white_input" id="AIuserText" autocomplete="off" placeholder="要和我聊什么呀?" />
<button type="submit" class="live_talk_send_btn" id="talk_send">发送</button>
</div>
</form>
</div>
<input name="live_talk" id="live_talk" value="1" type="hidden" />
<div class="live_ico_box" style="display:none;">
<div class="live_ico_item type_info" id="showInfoBtn"></div>
<div class="live_ico_item type_talk" id="showTalkBtn"></div>
<div class="live_ico_item type_music" id="musicButton"></div>
<div class="live_ico_item type_youdu" id="youduButton"></div>
<div class="live_ico_item type_quit" id="hideButton"></div>
<input name="live_statu_val" id="live_statu_val" value="0" type="hidden" />
<audio src="" style="display:none;" id="live2d_bgm" data-bgm="0" preload="none"></audio>
<input id="duType" value="douqilai" type="hidden" />
</div>
</div>
<div id="open_live2d">召唤伊斯特瓦尔</div>
<!-- <![endif]-->
<footer>
<p>
<small>Made with ❤ by Mayx<br />Last updated at 2025-11-05 17:47:55<br /> 总字数:608213 - 文章数:176 - <a href="/atom.xml" >Atom</a> - <a href="/README.html" >About</a></small>
</p>
</footer>
</div>
<script src="/assets/js/scale.fix.js"></script>
<!--[if !IE]> -->
<script src="/assets/js/main_new.js"></script>
<script src="/Live2dHistoire/live2d/js/live2d.js"></script>
<script src="/Live2dHistoire/live2d/js/message.js"></script>
<!-- <![endif]-->
</body>
</html>