惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Securelist
K
Kaspersky official blog
Scott Helme
Scott Helme
C
CXSECURITY Database RSS Feed - CXSecurity.com
GbyAI
GbyAI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - Franky
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Y
Y Combinator Blog
T
Threat Research - Cisco Blogs
L
LINUX DO - 热门话题
C
Cyber Attacks, Cyber Crime and Cyber Security
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
月光博客
月光博客
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
人人都是产品经理
人人都是产品经理
L
Lohrmann on Cybersecurity
Recorded Future
Recorded Future
Latest news
Latest news
V2EX - 技术
V2EX - 技术
T
The Exploit Database - CXSecurity.com
H
Heimdal Security Blog
F
Fortinet All Blogs
Cloudbric
Cloudbric
IT之家
IT之家
博客园 - 叶小钗
Microsoft Security Blog
Microsoft Security Blog
P
Proofpoint News Feed
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
AWS News Blog
AWS News Blog
H
Help Net Security
S
Security @ Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
Recent Announcements
Recent Announcements
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
F
Full Disclosure
S
Schneier on Security
S
Security Affairs
T
Tenable Blog

博客园 - 敏捷的水

程序员成长思维:把自己当做产品来发展 发展你的兴趣,而不是跟随你的兴趣 领导力:不要做个“好人” 当你是个锤子 做自己的CEO 我们为何难以升职加薪 程序员的自我修养系列(四):图形化表达 - 敏捷的水 - 博客园 程序员的自我修养系列(三):习惯付费 程序员的自我修养系列(二):从元编程到元认知 程序员的自我修养系列(一):聊聊专业和业余 如何向别人介绍我是一个程序员 领域驱动开发实践之路:我们是如何从领域驱动开发当中获益的 ES6+ 现在就用系列(二):let 命令 ES6+ 现在就用系列(一):为什么使用ES6+ - 敏捷的水 - 博客园 程序员之网络安全系列(六):动态密码 程序员之网络安全系列(五):数字证书以及12306的证书问题 程序员之网络安全系列(四):数据加密之非对称秘钥 程序员之网络安全系列(二):如何安全保存用户密码及哈希算法 程序员之网络安全系列(一):为什么要关注网络安全?
程序员之网络安全系列(三):数据加密之对称加密算法
敏捷的水 · 2016-01-11 · via 博客园 - 敏捷的水

系列目录:

前文回顾

假如,明明和丽丽相互不认识,明明想给丽丽写一封情书,让隔壁老王送去

  1. 如何保证隔壁老王不能看到情书内容?(保密性)
  2. 如何保证隔壁老王不修改情书的内容?(完整性)
  3. 如何保证隔壁老王不冒充明明?(身份认证)
  4. 如何保证明明不能否认情书是自己写的?(来源的不可否认)

上一节,我们使用了Hash算法保证了情书的完整性,也就是确保“隔壁王叔叔”没有修改明明的情书,那么这一节我们来看看如何保证“隔壁王叔叔”不能看到情书的内容,也就是保密性。

数据加密

要想不让别人看到数据,那么我们就们就需要对数据加密。

加密技术 是最常用的安全保密手段,利用技术手段把重要的数据变为乱码(加密)传送,到达目的地后再用相同或不同的手段还原(解密)。
加密包括两个元素:算法和密钥。一个加密算法是将普通的文本(或者可以理解的信息)与一窜数字(密钥)的结合,产生不可理解的密文的步骤,密钥是用来对数据进行编码和解码的一种算法。

举个例子:

假设我们要对LOVE加密,我们可以先定义字母的顺序ABCDEFGHIJKLMNOPQRSTUVWXYZ,然后我们让每个字母向后移动两位,那么LOVE就变为了NQXG

L------>N
O------>Q
V------>X
E------>
LOVE--->NQXG

我想这就是最简单的加密方式。

密钥加密技术的密码体制分为对称密钥体制和非对称密钥体制两种。

对数据加密的技术分为两类,即对称加密(私人密钥加密)和非对称加密(公开密钥加密)。对称加密以数据加密标准(DES,Data Encryption Standard)算法为典型代表,非对称加密通常以RSA(Rivest Shamir Ad1eman)算法为代表。对称加密的加密密钥和解密密钥相同,而非对称加密的加密密钥和解密密钥不同,加密密钥可以公开而解密密钥需要保密。

对称加密

对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥。
比如,我们给WORD文档设置密码1234, 那么其他人想要打开文档也必须输入1234才能打开。

常用加密算法:

  • DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
  • 3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
  • AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;
  • RC4,也是为 RSA Data Security, Inc. 开发的密码系统的商标名称。

传统的DES由于只有56位的密钥,从1997年开始,RSA公司发起了一个称作“向DES挑战”的竞技赛。在首届挑战赛上,罗克·维瑟用了96天时间破解了用DES加密的一段信息。1999年12月22日,RSA公司发起“第三届DES挑战赛(DES Challenge III)”。2000年1月19日,由电子边疆基金会组织研制的25万美元的DES解密机以22.5小时的战绩,成功地破解了 DES加密算法。DES已逐渐完成了它的历史使命。

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

对称加密算法的优点:

  • 算法公开
  • 计算量小
  • 加密速度快,加密效率高

对称加密算法的缺点

  • 加解密双方需要使用相同的秘钥
  • 秘钥管理很不方便,如果用户很多,那么秘钥的管理成几何性增长
  • 任何一方秘钥泄露,数据都不安全了

最后

通过本节,我们知道当明明给丽丽情书时,可以用DES或者AES对数据进行加密,即使“隔壁王叔叔”拿到信件也看不懂内容,同时使用上一节的Hash算法保证了情书的内容完整,但是这就需要明明和丽丽提前设置一个秘钥。

代码示例

下面的代码输出如下结果

I Love You, Li Li
Encrypeted: 0t9glwGMmwtGs8B4QCotyZkKf091WElCwG659QiVVw0=
Decrypeted: I Love You, Li Li

.NET 源码:

using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;

namespace AES
{
class MainClass
{
public static void Main (string[] args)
{
string password = "Don't believe wang shu shu";
string orginTextToSent = "I Love You, Li Li";
Console.WriteLine (orginTextToSent);

string encryptedText=EncryptText(orginTextToSent, password);

Console.WriteLine ("Encrypeted: " + encryptedText);

string DecryptedText = DecryptText (encryptedText, password);
Console.WriteLine ("Decrypeted: " + DecryptedText);

}

public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;

// Set your salt here, change it to meet your flavor:
// The salt bytes must be at least 8 bytes.
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

AES.Mode = CipherMode.CBC;

using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}

return encryptedBytes;
}

public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;

// Set your salt here, change it to meet your flavor:
// The salt bytes must be at least 8 bytes.
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

AES.Mode = CipherMode.CBC;

using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}

return decryptedBytes;
}

public static string EncryptText(string input, string password)
{
// Get the bytes of the string
byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

// Hash the password with SHA256
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

string result = Convert.ToBase64String(bytesEncrypted);

return result;
}

public static string DecryptText(string input, string password)
{
// Get the bytes of the string
byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);

string result = Encoding.UTF8.GetString(bytesDecrypted);

return result;
}

}
}