密码学基础与常见算法解析
密码学简介
保护秘密的技术已经存在了几个世纪。最早保护和隐藏数据不被对手获取的尝试可以追溯到埃及纪念碑上发现的古代铭文,当时使用了只有少数可信的人知道的特殊字母表。这种早期的安全形式被称为“模糊化”,至今仍以不同的形式存在。为了使这种方法有效,关键是要保护好秘密,比如上述例子中字母表的秘密含义。
后来,在第一次世界大战和第二次世界大战期间,找到万无一失的方法来保护重要信息变得至关重要。到了20世纪后期,随着电子技术和计算机的出现,人们开发出了复杂的算法来保护数据,从而催生了一个全新的领域——密码学。密码学算法旨在利用数学函数来实现既定的安全目标,其中一个用途是允许两个进程或用户之间进行安全的数据交换。
数字基础设施中“最薄弱环节”的重要性
在设计数字基础设施的安全性时,我们有时会过于强调单个实体的安全性,而没有对端到端的安全给予必要的关注。这可能导致我们忽视系统中的一些漏洞和弱点,而黑客后来可能会利用这些漏洞来访问敏感数据。需要记住的重要一点是,数字基础设施作为一个整体,其强度取决于其最薄弱的环节。对黑客来说,这个最薄弱的环节可以为他们提供进入数字基础设施中敏感数据的后门。在某些情况下,如果不关闭所有后门,加强前门的防护并没有太大的好处。
随着保护数字基础设施的算法和技术变得越来越复杂,攻击者也在不断升级他们的技术。始终要记住,攻击者入侵数字基础设施最简单的方法之一就是利用这些漏洞来获取敏感信息。例如,2014年,加拿大联邦研究机构——国家研究委员会(NRC)遭受了一次网络攻击,估计损失数亿美元。攻击者利用了网络服务器上使用的Apache软件中的一个漏洞,窃取了数十年的研究数据和知识产权材料。
密码学基本术语
- 密码(Cipher) :执行特定密码功能的算法。
- 明文(Plain text) :普通数据,可以是文本文件、视频、位图或数字化语音,用P表示。
- 密文(Cipher text) :对明文应用密码学后得到的乱码文本,用C表示。
- 密码套件(Cipher suite) :一组密码软件组件。当两个独立的节点想使用密码学交换消息时,他们首先需要就一个密码套件达成一致,以确保使用相同的密码功能实现。
- 加密(Encryption) :将明文P转换为密文C的过程,数学表示为encrypt(P) = C。
- 解密(Decryption) :将密文转换回明文的过程,数学表示为decrypt(C) = P。
- 密码分析(Cryptanalysis) :分析密码算法强度的方法,分析人员试图在不获取秘密的情况下恢复明文。
- 个人身份信息(Personally Identifiable Information, PII) :单独或与其他相关数据一起使用时可用于追踪个人身份的信息,如社会安全号码、出生日期或母亲的娘家姓氏。
理解系统的安全需求
首先了解系统的确切安全需求非常重要,这有助于我们使用正确的密码技术并发现系统中潜在的漏洞。一种更好地理解系统安全需求的方法是回答以下四个问题:
1. 哪些个人或进程需要受到保护?
2. 我们要保护这些个人和进程免受谁的侵害?
3. 我们应该在哪里保护他们?
4. 我们为什么要保护他们?
以AWS云中的虚拟专用云(VPC)为例,VPC允许我们创建一个逻辑隔离网络,并在其中添加虚拟机等资源。为了理解VPC的安全需求,我们需要通过回答上述四个问题来确定相关身份信息:
- 有多少人计划使用这个系统?
- 需要保护哪些类型的信息?
- 我们是只需要保护VPC,还是需要对发送到系统并传输到VPC的消息进行加密?
- 数据的安全分类是什么?潜在风险有哪些?为什么有人会有动机尝试攻击这个系统?
大多数问题的答案可以通过以下三个步骤得出:
1.
识别实体
:实体可以定义为信息系统中的个人、进程或资源。我们首先需要确定运行时存在哪些用户、资源和进程,然后量化这些已识别实体的安全需求,无论是单独还是作为一个群体。一旦更好地理解了这些需求,我们就可以为数字系统制定安全目标。
2.
确定安全目标
:设计安全系统的目标是保护信息不被窃取、破坏或攻击。密码算法通常用于实现一个或多个安全目标:
-
认证(Authentication)
:确定用户、设备或系统的身份,确认它们确实是其所声称的身份。
-
授权(Authorization)
:给予用户访问特定资源或功能的权限。
-
机密性(Confidentiality)
:需要保护的数据称为敏感数据。机密性是指将敏感数据限制仅授权用户访问。为了在敏感数据传输或存储过程中保护其机密性,需要使用加密算法使数据除授权用户外不可读。
-
完整性(Integrity)
:确保数据在传输或存储过程中没有以任何方式被更改。例如,TCP/IP(传输控制协议/互联网协议)使用校验和或循环冗余校验(CRC)算法来验证数据的完整性。
-
不可否认性(Non - repudiation)
:能够提供不可伪造和无可辩驳的证据,证明消息已发送或接收。这些证据可用于后续证明数据的接收情况。
3.
理解数据的敏感性
:了解数据的分类性质很重要。监管机构(如政府、机构或组织)会根据数据泄露后的严重后果对数据进行分类。数据分类有助于我们选择正确的密码算法。根据数据包含信息的敏感性,有多种分类方式,常见的分类如下:
-
公开数据或未分类数据
:可供公众使用的任何数据,如公司网站或政府信息门户上的信息。
-
内部数据或机密数据
:虽然不供公众使用,但公开这些数据可能不会造成严重后果。例如,员工抱怨经理的电子邮件被公开,可能会让公司尴尬,但不会造成严重损害。
-
敏感数据或秘密数据
:不应该供公众使用的数据,公开这些数据可能会对个人或组织造成损害。例如,泄露未来iPhone的细节可能会损害苹果的商业目标,并使竞争对手(如三星)受益。
-
高度敏感数据
:也称为绝密数据。这类信息一旦泄露,将对组织造成极其严重的损害。例如,专有研究、战略业务计划或内部财务数据。绝密数据通过多层安全措施进行保护,需要特殊权限才能访问。
简单密码的基本设计
密码设计的目的是找到一种算法,能够对敏感数据进行加密,使恶意进程或未经授权的用户无法访问。随着时间的推移,密码变得越来越复杂,但密码所基于的基本原理保持不变。我们先从一些相对简单的密码开始,了解密码算法设计的基本原理。
替换密码
替换密码已经以各种形式使用了数百年。顾名思义,替换密码基于一个简单的概念:以预定、有组织的方式将明文中的字符替换为其他字符。具体步骤如下:
1. 首先,将每个字符映射到一个替换字符。
2. 然后,使用替换映射将明文中的每个字符替换为密文中的另一个字符,从而将明文编码转换为密文。
3. 解码时,使用替换映射恢复明文。
常见的基于替换的密码有:
-
凯撒密码(Caesar cipher)
:基于替换映射,通过应用一个简单的、保密的公式来确定性地改变实际字符串。替换映射是将每个字符替换为其右侧第三个字符。例如,使用Python实现凯撒密码的代码如下:
rotation = 3
P = 'CALM'; C=''
for letter in P:
C = C+ (chr(ord(letter) + rotation))
print(C)
运行上述代码,对明文“CALM”应用凯撒密码后,输出的密文为“FDOP”。凯撒密码简单易实现,但缺点是不太安全,因为黑客可以简单地遍历字母表的所有可能移位(共26种),看看是否能出现连贯的消息。鉴于当前计算机的处理能力,这是一个相对较小的组合数,因此不应用于保护高度敏感的数据。据说凯撒曾使用这种密码与他的顾问进行通信。
-
ROT13
:是凯撒密码的一种特殊情况,其中替换映射是将每个字符替换为其右侧第13个字符。例如,使用Python实现ROT13的代码如下:
rotation = 13
P = 'CALM'; C=''
for letter in P:
C = C+ (chr(ord(letter) + rotation))
print(C)
运行上述代码,对明文“CALM”应用ROT13后,输出的密文为“PNYZ”。ROT13实际上并不用于实现数据的机密性,更多地用于掩盖文本,例如隐藏可能冒犯性的文本,或者避免泄露谜题的答案等。
替换密码简单易实现和理解,但也容易被破解。简单的密码分析表明,如果使用英文字母表,破解这种密码只需要确定字符的移位量。我们可以逐个尝试英文字母,直到能够解密文本,大约需要25次尝试就能重建明文。
换位密码
在换位密码中,明文的字符通过换位进行加密。换位是一种加密方法,通过确定性逻辑打乱字符的位置。换位密码将字符按行写入矩阵,然后按列读取作为输出。例如,对于明文“Ottawa Rocks”,使用3x4的矩阵并按水平方向写入明文:
O t t a
w a R o
c k s
按垂直方向读取字符串,生成的密文为“OwctaktRsao”。这里的密钥是{1,2,3,4},即列的读取顺序。如果使用不同的密钥,如{2,4,3,1},则会得到不同的密文,在这种情况下为“takaotRsOwc”。
常见的密码学技术类型
不同类型的密码学技术使用不同的算法,并在不同的情况下使用。由于不同的情况和用例根据业务需求和数据分类有不同的安全要求,因此选择正确的技术对于设计良好的架构至关重要。大致来说,密码学技术可以分为以下三种类型:
-
哈希
-
对称加密
-
非对称加密
在第一次世界大战中,德国人使用了一种名为ADFGVX的密码,它结合了换位和替换密码。多年后,该密码被乔治·潘文破解。
密码哈希函数
密码哈希函数是一种数学算法,可用于为消息创建唯一的“指纹”。它从明文创建一个输出,称为哈希值。输出的大小通常是固定的,但对于一些特殊算法可能会有所不同。数学表示为:C1 = hashFunction(P1),其中P1是表示输入数据的明文,C1是由密码哈希函数生成的固定长度的哈希值。
密码哈希函数的关键特性如下:
-
确定性
:相同的输入(明文)总是产生相同的输出(哈希值)。无论对特定数据进行多少次哈希处理,结果都保持一致。
-
唯一性
:理想情况下,不同的输入应该总是产生唯一的哈希输出。如果两个不同的输入产生相同的哈希值,则称为“碰撞”。优质的哈希函数旨在将碰撞的可能性降至最低。
-
固定长度
:哈希函数的输出长度是固定的,无论输入数据的大小如何。例如,MD5生成128位的哈希值,SHA - 256生成256位的哈希值。
-
对输入变化敏感
:即使明文中有微小的改动,也会导致生成的哈希值发生显著且不可预测的变化。这确保了无法从哈希值推导出原始输入,或者找到另一个产生相同哈希值的输入,从而增强了哈希函数的安全性。
-
单向函数
:哈希函数是单向的,即从哈希值(C1)反向生成原始明文(P1)在计算上是不可行的。这确保了即使未经授权的一方获得了哈希值,也无法用它来确定原始数据。
如果每个唯一的消息没有唯一的哈希值,就会发生碰撞。在安全应用中,碰撞是一个潜在的漏洞,其发生概率应该非常低。
实现密码哈希函数
密码哈希函数可以通过各种算法实现,下面详细介绍两种常见的算法:
-
MD5
:由Poul - Henning Kamp于1994年开发,用于取代MD4。它生成128位的哈希值,相当于16字节或32个十六进制字符。无论原始数据的大小如何,哈希值始终是128位长,其目的是为原始数据创建一个“指纹”或“摘要”。MD5是一种相对简单的算法,但容易发生碰撞。在不能容忍碰撞的应用中,不应使用MD5。例如,它可以用于检查从互联网下载的文件的完整性。
以下是使用Python生成MD5哈希值的示例代码:
import hashlib
def generate_md5_hash(input_string):
# Create a new md5 hash object
md5_hash = hashlib.md5()
# Encode the input string to bytes and hash it
md5_hash.update(input_string.encode())
# Return the hexadecimal representation of the hash
return md5_hash.hexdigest()
def verify_md5_hash(input_string, correct_hash):
# Generate md5 hash for the input_string
computed_hash = generate_md5_hash(input_string)
# Compare the computed hash with the provided hash
return computed_hash == correct_hash
# Test
input_string = "Hello, World!"
hash_value = generate_md5_hash(input_string)
print(f"Generated hash: {hash_value}")
correct_hash = hash_value
print(verify_md5_hash(input_string, correct_hash))
在上述代码中,
generate_md5_hash
函数用于生成输入字符串的MD5哈希值,
verify_md5_hash
函数用于验证输入字符串的哈希值是否与已知的正确哈希值匹配。运行代码后,会输出生成的哈希值和验证结果。
MD5在20世纪90年代后期被发现存在弱点,但由于其简单性,至今仍被广泛使用。它适合用于数据的完整性检查,但不能用于证明文件的真实性,因为MD5消息摘要不是签名哈希,不能唯一地将哈希值与所有者关联起来。
-
安全哈希算法(SHA)
:由美国国家标准与技术研究院(NIST)开发,广泛用于验证数据的完整性。其中,SHA - 512是一种流行的哈希函数,Python的
hashlib
库中包含了它。以下是使用Python通过SHA算法创建哈希值的示例:
import hashlib
salt = "qIo0foX5"
password = "myPassword"
在上述代码中,首先导入了
hashlib
库,然后定义了一个盐(salt)和一个密码。加盐是在对密码进行哈希处理之前添加随机字符的做法,它通过增加哈希碰撞的难度来增强安全性。后续可以继续使用
hashlib
库中的SHA相关函数对加盐后的密码进行哈希处理。
密码学基础与常见算法解析
对称加密算法
对称加密算法使用相同的密钥进行加密和解密。在对称加密系统中,发送方和接收方共享一个秘密密钥,发送方使用该密钥将明文转换为密文,接收方使用相同的密钥将密文还原为明文。
工作原理
对称加密的基本流程如下:
1. 生成一个共享密钥,发送方和接收方都拥有该密钥。
2. 发送方使用密钥对明文进行加密,生成密文。
3. 密文通过不安全的信道传输给接收方。
4. 接收方使用相同的密钥对密文进行解密,恢复出明文。
常见的对称加密算法有DES(Data Encryption Standard)、3DES(Triple DES)和AES(Advanced Encryption Standard)等。
优缺点
-
优点
:
- 加密和解密速度快,适合处理大量数据。
- 实现相对简单,所需的计算资源较少。
-
缺点
:
- 密钥管理困难,因为发送方和接收方需要安全地共享密钥。如果密钥泄露,整个通信的安全性将受到威胁。
- 扩展性较差,当有多个用户需要进行安全通信时,密钥的分发和管理会变得非常复杂。
非对称加密算法
非对称加密算法使用一对密钥,即公钥和私钥。公钥可以公开分发,而私钥则由用户秘密保存。公钥用于加密消息,私钥用于解密消息。
工作原理
非对称加密的基本流程如下:
1. 用户生成一对密钥,公钥和私钥。
2. 发送方使用接收方的公钥对明文进行加密,生成密文。
3. 密文通过不安全的信道传输给接收方。
4. 接收方使用自己的私钥对密文进行解密,恢复出明文。
常见的非对称加密算法有RSA、DSA(Digital Signature Algorithm)和ECC(Elliptic Curve Cryptography)等。
优缺点
-
优点
:
- 密钥管理相对简单,公钥可以公开分发,不需要像对称加密那样进行安全的密钥共享。
- 提供了更好的安全性,因为私钥只有用户自己知道,即使公钥被泄露,攻击者也无法解密消息。
- 可以用于数字签名,确保消息的真实性和不可否认性。
-
缺点
:
- 加密和解密速度较慢,不适合处理大量数据。
- 所需的计算资源较多,对系统性能有一定的影响。
数字证书
数字证书是一种用于验证用户身份和公钥的有效性的电子文档。它由证书颁发机构(CA)签发,包含了用户的公钥、身份信息和CA的数字签名。
工作原理
数字证书的基本流程如下:
1. 用户向CA申请数字证书,提交自己的公钥和身份信息。
2. CA验证用户的身份信息,并使用自己的私钥对用户的公钥和身份信息进行签名,生成数字证书。
3. 用户获得数字证书后,可以将其公开分发。
4. 当其他用户需要与该用户进行安全通信时,他们可以获取该用户的数字证书,并使用CA的公钥验证证书的有效性。如果证书有效,他们就可以使用证书中包含的公钥进行加密通信。
作用
- 身份验证 :数字证书可以确保通信双方的身份真实可靠。
- 公钥分发 :数字证书可以安全地分发公钥,避免公钥被篡改或伪造。
- 数据完整性 :数字证书中的数字签名可以确保证书内容的完整性,防止证书被篡改。
实际应用示例
假设我们要实现一个简单的安全通信系统,使用对称加密和非对称加密相结合的方式。具体步骤如下:
- 生成密钥对 :接收方使用非对称加密算法生成一对公钥和私钥。
- 分发公钥 :接收方将公钥通过数字证书的方式分发给发送方。
- 生成对称密钥 :发送方使用接收方的公钥对一个随机生成的对称密钥进行加密。
- 传输对称密钥 :加密后的对称密钥通过不安全的信道传输给接收方。
- 解密对称密钥 :接收方使用自己的私钥对加密后的对称密钥进行解密,得到对称密钥。
- 加密消息 :发送方使用对称密钥对要发送的消息进行加密,生成密文。
- 传输密文 :密文通过不安全的信道传输给接收方。
- 解密消息 :接收方使用相同的对称密钥对密文进行解密,恢复出明文。
以下是一个使用Python实现上述流程的示例代码:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, AES
import os
# 生成RSA密钥对
def generate_rsa_key_pair():
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key
# 使用公钥加密对称密钥
def encrypt_symmetric_key(symmetric_key, public_key):
recipient_key = RSA.import_key(public_key)
cipher_rsa = PKCS1_OAEP.new(recipient_key)
enc_session_key = cipher_rsa.encrypt(symmetric_key)
return enc_session_key
# 使用私钥解密对称密钥
def decrypt_symmetric_key(enc_session_key, private_key):
key = RSA.import_key(private_key)
cipher_rsa = PKCS1_OAEP.new(key)
session_key = cipher_rsa.decrypt(enc_session_key)
return session_key
# 使用对称密钥加密消息
def encrypt_message(message, symmetric_key):
cipher = AES.new(symmetric_key, AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(message.encode())
return nonce, tag, ciphertext
# 使用对称密钥解密消息
def decrypt_message(nonce, tag, ciphertext, symmetric_key):
cipher = AES.new(symmetric_key, AES.MODE_EAX, nonce=nonce)
try:
data = cipher.decrypt_and_verify(ciphertext, tag)
return data.decode()
except ValueError:
return None
# 主程序
if __name__ == "__main__":
# 生成RSA密钥对
private_key, public_key = generate_rsa_key_pair()
# 生成对称密钥
symmetric_key = os.urandom(16)
# 加密对称密钥
enc_session_key = encrypt_symmetric_key(symmetric_key, public_key)
# 解密对称密钥
decrypted_symmetric_key = decrypt_symmetric_key(enc_session_key, private_key)
# 要发送的消息
message = "Hello, World!"
# 加密消息
nonce, tag, ciphertext = encrypt_message(message, decrypted_symmetric_key)
# 解密消息
decrypted_message = decrypt_message(nonce, tag, ciphertext, decrypted_symmetric_key)
print(f"Original message: {message}")
print(f"Decrypted message: {decrypted_message}")
总结
密码学在现代信息安全中起着至关重要的作用。通过使用哈希函数、对称加密和非对称加密等技术,我们可以确保数据的机密性、完整性和真实性。在实际应用中,我们需要根据具体的需求和场景选择合适的密码学算法和技术,并注意密钥的管理和安全。同时,数字证书可以帮助我们安全地分发公钥和验证用户身份,进一步增强通信的安全性。希望通过本文的介绍,你对密码学有了更深入的了解,并能够在实际项目中正确应用这些技术。
超级会员免费看
3431

被折叠的 条评论
为什么被折叠?



