加密值法
现在流行的有两种,一种是加密后不可逆的但是每个值加密后都是唯一的,比如MD5,用在用户密码设置。本地在发送密码前先进行md5加密,然后直接存在用户服务器中。下次登录分别都是在输入密码后进行加密再跟服务器端数据库中的同样的加密码进行匹配。但是现在很多人都在穷举法一个个的将输入和输出进行匹配,现在很多简单密码加密后的md5都可以当查字典一样查到。
还有一种是公钥和私钥的加密方法。公钥和私钥分别代表两个值, 数据进行加密依靠这两个值进行操作,操作完后,私钥留在本地,公钥和加密文发给另外一方,另外一方也有私钥所以可以解密但是中途任何人截获到了因为没有私钥都不能解密。这个一般用在VPN和网银。 网银的那个长得像u盘的东西里面存的就是私钥和解密程序是不可读的。不过这个方法一样有弊端,任何人泄露了其中的东西整个加密系统就会瓦解。
所以没有绝对安全的加密算法
B. 如何防止单片机内部代码被窃取
通常情况下可以采用将单片机上锁,也就是通过锁掉芯片防止单片机内部的image被盗。上锁后的芯片外部的调试接口将不能访问片内地址。例如飞思卡尔的Kinetis系列微处理器都是可以给芯片加锁,加锁的过程是在Flash配置区域写入加密值。
C. 别再用简单版MD5加密了,大佬们都这么是使用——>MD5盐值加密多方法详解
MD5加密,尽管曾经广泛应用,但由于其易被破解,现在已经不再被视为安全的加密手段。实际上,MD5的单向加密特性使其容易遭受暴力破解攻击。因此,现代开发实践中,大佬们更倾向于使用MD5盐值加密,以提高安全性。
MD5盐值加密是一种在原始MD5值中加入随机盐值的增强版加密方法,使得即使相同的输入,经过盐值处理后的输出也会不同。它提供了更好的身份验证和数据保护。Apache的DigestUtils工具可以用来实现MD5盐值加密,但推荐使用Spring框架提供的BCryptPasswordEncoder,如需自定义盐值,可以按照其规则操作。
在使用BCryptPasswordEncoder时,虽然加密结果看起来不同,但通过工具提供的校验方法,我们可以在数据库中存储盐值,确保安全验证。总的来说,MD5盐值加密通过引入随机性,有效提高了数据的安全性,是现代开发者应当优先选择的加密方式。
如果你对这些内容感兴趣,或者觉得有帮助,不妨给予支持,比如点赞或分享。我将持续分享更多知识,期待你的关注!
D. 数据库里加密的密码是怎么实现的
C#中有数据加密的类using System.Security.Cryptography,在这个类中你可以调用它的两个方法分别是加密方法
public static string Encrypt(string text)
{}
解密方法
public static string Decrypt(string text)
{}
我们一般使用连接数据库加密的话,都会使用一个配置文件在配置文件中对数据库链接进行读写,通过加密方法把链接写到配置文件,然后读取的时候再使用解密方法。
希望可以帮到你,谢谢!
E. 零知识证明
https://arxiv.org/abs/1906.07221
零知识简洁的非交互知识论证(zk SNARK)是一种真正巧妙的方法,可以在不透露任何其他信息的情况下证明某件事是真的,然而,为什么它首先是有用的呢?
零知识证明在无数应用中是有利的,包括:
关于私人数据的证明声明:
匿名授权:
匿名付款:
外包计算:
尽管表面上听起来很棒,但底层方法是数学和密码学的“奇迹”,自 1985 年在主要着作“交互式证明系统的知识复杂性中引入以来,已经进行了第四个十年的研究 随后引入了非交互式证明,这在区块链的背景下尤为重要。
在任何零知识证明系统中,都有一个验证人想要说服验证人某些陈述是真实的,而不披露任何其他信息,例如,验证人了解到验证人的银行账户中有X多个,但没有其他信息(即,未披露实际金额)。协议应满足三个属性:
让我们从简单开始,并尝试证明某些东西,而不必担心零知识,非交互性,其形式和适用性。
想象一下,我们有一个长度为 10 数组,我们想向验证者(例如程序)证明所有这些位都设置为 1,即我们知道一个数组,使得每个元素都等于 1。
验证者一次只能检查 (即读取) 一个元素。为了验证语句,可以通过以某种任意顺序读取元素,并检查它是否真正等于1,如果是,则在第一次检查后该语句的置信度为10%,或者如果该位不等于1,则语句完全无效。验证者必须进入下一轮,直到他获得足够的信心。在一些情况下,可以信任证明者并且只需要50% 置信度,在需要95% 置信度的其他情况下,必须检查所有单元。很明显,这种证明协议的缺点是,必须进行与元素数量成比例的检查数量,如果我们考虑数百万个元素的数组,这是不切实际的。
让我们考虑多项式,有一个曲线对应于多项式: 。多项式有一个有利的性质,即如果我们有两个不相等的次数最多为 d 的多项式,它们相交的点不超过 d。 例如,让我们稍微修改原始多项式 。如果我们想找到两个多项式的交点,我们需要将它们等同起来。例如,要找到多项式与x轴相交的位置 (即 ),我们将 等同,并且此类方程的解将是那些共享点: , 和 。
同样,我们可以将多项式的原始版本和修改版本等同起来,以找到它们的交点。所得的多项式为1,且有明显的解 。因此只有一个交点。
对于任意次数为 d 的多项式,任何此类方程的结果始终是另一个次数最多为 d 的多项式,因为没有乘法可以产生更高的次数。 示例: ,简化为 。代数基本定理告诉我们,d 次多项式最多可以有 d 个解。因此,我们可以得出结论,任意点处的任何多项式的求值类似于其唯一身份的表示。让我们在x = 10处评估我们的示例多项式。
事实上,在所有要计算的x选项中,最多只有3个选项在这些多项式中具有相同的计算,而所有其他选项都会不同。这就是为什么如果证明者声称知道一些多项式 (无论其次数有多大),他们可以遵循一个简单的协议来验证语句:
例如,如果我们考虑 x 从 1 到 的整数范围,则评估不同的点数为 。 此后,x 意外“击中”任何 个共享点的概率等于 ,这被认为可以忽略不计。
注意:与无效位检查协议相比,新协议只需要一轮,并且在声明中给出了压倒性的信心(假设 d 充分小于范围的上限,几乎 100%)。
这就是为什么多项式是zk-SNARK的核心,尽管也可能存在其他证明介质。
我们从证明多项式知识的问题开始,然后采用通用方法。 在此过程中,我们将发现多项式的许多其他性质。 到目前为止的讨论集中,关注一个弱的证明概念上,即各方必须相互信任,因为还没有措施来执行协议的规则。 例如,证明者不需要知道多项式,他可以使用任何其他可用的方法来得出正确的结果。 此外,如果验证者的多项式评估的幅度不大,比如说 10,验证者可以猜测一个数字,并且它被接受的概率是不可忽略的。 我们必须解决协议的这种弱点,但首先知道多项式意味着什么? 多项式可以表示为以下形式(其中 n 是多项式的次数):
如果有人说他知道一个 1 次多项式(即 ),那意味着他真正知道的是系数 。 此外,系数可以有任何值,包括 0。让我们说,证明者声称知道3次多项式,使得x = 1和x = 2是所有可能解中的两个。这样的有效多项式之一是 。
代数的基本定理指出,只要多项式是可解的,任何多项式都可以分解为线性多项式 (即代表直线的1次多项式)。因此,我们可以将任何有效多项式表示为其因子的乘积:
同样,如果这些因子中的任何一个为零,则整个方程为零,因此,所有 都是唯一的解。我们的示例可以分解为以下多项式:
x的值是:0,1,2,你可以很容易地在多项式的任一形式上检查这一点。
回到证明者声称他知道根为 1 和 2 的 3 次多项式,这意味着他的多项式具有以下形式:
换句话说,(x − 1) 和 (x − 2) 是所讨论的多项式的余因子。因此,如果证明者想要证明他的多项式确实具有这些根而不公开多项式本身,则他需要证明他的多项式p(x) 是那些协因子 的乘法,称为目标多项式,和一些任意多项式h(x) ,即:
换句话说,p(x) 具有t(x) 的所有根。找到h(x) 的自然方法是通过除法 。如果证明者找不到这样的h(x),这意味着p(x) 没有必要的协因子t(x),在这种情况下,多项式除法将具有余数。在我们的示例中,如果我们将 除以 。我们得到了无余数的结果 。
使用我们的多项式身份检查协议,我们可以比较多项式 和 :
为了将其付诸实践,让我们在示例中执行此协议:
相反,如果证明者使用不同的 ,它没有正确的辅因子,例如 ,那么:
我们将得到 ,余数为 ,即: 。这意味着证明者必须将余数除以 才能评估 。因此,由于验证者对x的随机选择,因此对于余数 被t(x) 整除的概率很低,因此,如果验证者将检查p和h补是整数,这样的证明将被拒绝。但是,该检查要求多项式系数也必须是整数。
现在,我们可以在不学习多项式本身的情况下检查多项式的特定属性,因此这已经为我们提供了某种形式的零知识和简洁。尽管如此,此构造仍存在多个问题:
我们将在以下部分解决所有问题。
在上文中,如果将 和 不是明文给出,而是作为黑匣子给出,那将是理想的选择,因此人们无法篡改协议,但仍然能够计算对这些模糊值。类似于哈希函数,因此在计算时很难返回到原始输入。
这正是同态加密的目的。也就是说,它允许对一个值进行加密,并能够对这种加密应用算术运算。有多种方法可以实现加密的同态特性,我们将简要介绍一种简单的方法。
一般的想法是,我们选择一个基数的自然数g(比如5),然后对一个值进行加密,我们将g乘以该值的幂。例如,如果我们想要加密数字3:
其中125是3的加密。如果要将这个加密的数字乘以2,则将其提高为2的指数:
我们能够将未知值乘以2,并对其进行加密。我们还可以通过乘法添加两个加密值,例如3+2:
同样,我们可以通过除法减去加密的数字,例如5 − 3:
但是,由于基数5是公共的,因此很容易回到秘密数字,将加密的数字除以5,直到结果为1。除法的次数即为明文。
这就是模算法发挥作用的地方。模运算的思想如下:我们声明只选择前n个自然数,即0,1,…,n-1而不是拥有一个无限的数字集。如果任何给定的整数不在这个范围内,我们将其“环绕”。例如,让我们先选择六个数字。为了说明这一点,请考虑一个具有六个相等单位刻度的圆;这是我们的射程。
现在让我们看看数字8将落在哪里。 打个比方,我们可以把它想象成一根绳子,它的长度是八个单位。如果我们把绳子连接到圆圈的开头并开始将绳子缠绕在它周围,旋转一圈后,我们还剩下一部分绳子.因此,如果我们继续这个过程,绳子将在2处结束。
它是模运算的结果。 不管绳子有多长,它总是会停在圆圈的刻度之一处。 因此,模运算将使其保持在一定范围内。 15 个单位的绳索将在 3 处停止,即 6 + 6 + 3(两个完整的圆圈,剩余 3 个单位)。 负数的工作方式相同,唯一的区别是我们将其包装在相反的方向,对于 -8,结果将是 4。
而且,我们可以进行算术运算,结果总是在n个数的范围内。 我们现在将使用符号“mod ”来表示数字的范围。 例如:3 × 5 = 3 (mod 6); 5 + 2 = 1 (mod 6).
此外,最重要的特性是运算顺序无关紧要,例如,我们可以先执行所有运算,然后在每次运算后应用模或应用模。例如: 相当于:2 × 4 = 2 (mod 6); 2 − 1 = 1 (mod 6); 1 × 3 = 3 (mod 6).
那到底为什么有帮助呢?事实证明,如果我们使用模算术,则具有运算结果,回到原始数字是不平凡的,因为许多不同的组合将具有相同的结果: 5 × 4 = 2 (mod 6); 4 × 2 = 2 (mod 6); 2 × 1 = 2 (mod 6).
如果没有模算术,结果的大小为它的解决方案提供了线索。 否则,这条信息会被隐藏,而常见的算术属性会被保留。
如果我们回到同态加密并使用模运算,例如模 7,我们将得到:
和不同的指数会有相同的结果:
这是很难找到指数的地方。 事实上,如果模数足够大,这样做就变得不可行,而现代密码学的很大一部分是基于这个问题的“难度”。该方案的所有同态属性都保留在模领域中:
encryption:
multiplication:
addition:
让我们明确说明加密函数: ,其中 v 是我们要加密的值。
这种同态加密方案存在局限性,尽管我们可以将加密值乘以未加密值,但我们不能将两个加密值乘以 (和除以),也不能对加密值求幂。虽然从第一印象来看是不幸的,但这些属性将成为zk-SNARK的基石。
有了这样的工具,我们现在可以评估一个加密随机值为x的多项式,并相应地修改零知识协议。
让我们看看如何评估多项式 。正如我们以前建立的那样,多项式就是知道它的系数,在这种情况下,它们是: 1,-3,2。因为同态加密不允许对加密值求幂,所以我们必须得到从1到3的x幂的加密值: , , ,这样我们可以对加密多项式求值如下:
作为这些操作的结果,我们在我们未知的某个 x 处对我们的多项式进行了加密。 这是一个非常强大的机制,并且由于同态特性,相同多项式的加密计算在加密空间中总是相同的。我们现在可以更新协议的先前版本,对于d次多项式:
Verifier:
Prover:
Verifier:
由于证明者对s一无所知,因此很难提出不合法但仍匹配的评估。
虽然在这样的协议中,证明者的敏捷性是有限的,但他仍然可以使用任何其他方法来伪造证明,而无需实际使用所提供的 s 幂的加密,例如,如果证明者声称仅使用 2 次幂 和 有一个令人满意的多项式 ,这在当前协议中无法验证。
多项式的知识是其系数 。 我们在协议中“分配”这些系数的方式是通过对秘密值 s 的相应加密幂求幂(即 )。 我们已经在选择 s 的加密幂时限制了证明者,但这种限制并未强制执行,例如,可以使用任何可能的方法来找到满足方程 的任意值 和 并将它们提供给验证者而不是 和 。 例如,对于一些随机 , 和 ,其中 可以从提供的 s 的加密幂计算。 这就是为什么验证者需要证明仅使用 s 的幂的加密来计算 和 而没有别的。
让我们考虑一个1次多项式的基本例子,该多项式具有一个变量和一个系数 ,相应地,s的加密 。我们正在寻找的是确保只有s的加密,即 ,被一些任意系数c同态“乘以”,而不是其他任何东西。所以对于任意的c,结果必须是 形式。
一种方法是要求对另一个移位的加密值与原始值一起执行相同的操作,充当“校验和”的算术模拟,确保结果是原始值的取幂。这是通过引入的指数知识假设Knowledge-of-Exponent Assumption (或KEA) 来实现的,更确切地说:
Alice有一个值a,她希望Bob指数到任何幂,唯一的要求是只有这个a可以指数,没有别的,以确保她:
因为 Bob 无法从元组 中提取 ,因此推测 Bob 可以产生有效响应的唯一方法是通过以下过程:
最终,这样的协议向Alice提供了一个证据,证明Bob确实将a乘以他已知的某个值,并且他不能进行任何其他操作,例如乘法、加法,因为这将消除 移位关系。
在同态加密上下文中,幂运算是加密值的乘法。我们可以在简单的单系数多项式 的情况下应用相同的构造:
这种结构限制证明者仅使用提供的加密 s,因此证明者可以仅将系数 c 分配给验证者提供的多项式。 我们现在可以将这种单项多项式方法缩放为多项多项式,因为每个项的系数分配是单独计算的,然后同态地“相加”在一起。 因此,如果向证明者提供 s 的加密幂以及它们的移位值,他可以评估原始多项式和移位多项式,其中必须进行相同的检查。 特别是对于 d 次多项式:
对于我们之前的示例多项式 ,这将是:
现在我们可以确定,验证程序除了使用验证程序提供的多项式外,没有使用任何其他方法,因为没有其他方法来保持 移位。此外,如果验证者希望确保在验证者的多项式中排除一些s的幂,例如j,他将不提供加密 及其移位 。
与我们一开始的相比,我们现在有了一个健壮的协议。 然而,无论加密如何,零知识属性仍然存在一个明显的缺点:虽然理论上多项式系数 可以有很大范围的值,但实际上它可能非常有限(上例中为 6),这意味着 验证者可以暴力破解有限范围的系数组合,直到结果等于证明者的答案。 例如,如果我们考虑每个系数的 100 个值的范围,则 2 次多项式将总共有 100 万个不同的组合,考虑到蛮力将需要不到 100 万次迭代。 此外,即使在只有一个系数且其值为 1 的情况下,安全协议也应该是安全的。
因为验证器只能从验证器发送的数据中提取关于未知多项式p(x)的知识,所以让我们考虑那些提供的值(证明): 。他们参与以下检查:
gp=gh(多项式p(x)有t(x)的根)
(gp)α=gp′t(s)(使用正确形式的多项式)
问题是我们如何改变证据,使支票仍然有效,但无法提取任何知识?从上一节可以得出一个答案:我们可以用一些随机数δ(δ)来“移位”这些值,例如(gp)δ。现在,为了提取知识,首先需要找到被认为不可行的δ。此外,这种随机化在统计学上与随机性是无法区分的。
为了保持关系,让我们检查验证者的检查。证明者的值之一位于方程式的每一侧。因此,如果我们用相同的 δ “移动” 它们中的每一个,方程必须保持平衡。
具体地,证明者对随机 δ 进行采样,并用g α p(s) δ gh(s) δ 对其证明值求幂,并提供给验证者进行验证:
(gp)δ = gh δ t(s) (gp)δ α = gp′ δ
合并后,我们可以观察到支票仍然有效:
注意: 零知识是多么容易被编织到建筑中,这通常被称为 “免费” 零知识。
到目前为止,我们有一个交互式零知识方案。为什么会这样?由于该证明仅对原始验证者有效,其他任何人(其他验证者)都不能信任同一证明,因为:
因此,为了证明语句(在这种情况下是多项式的知识),需要与每个验证者进行单独的交互。
虽然交互式证明系统有其使用案例,例如,当证明人只想说服一个专用的验证人(称为指定验证人),这样证明就不能再用于向其他人证明同一陈述时,当一个人需要同时(例如,在区块链等分布式系统中)或永久地说服多方时,这是非常有效的。验证方需要始终保持在线,并对每个验证方执行相同的计算。
因此,我们需要的秘密参数是可重用的,公开的,可信的和不可滥用的。
让我们首先考虑在秘密 (t(s),α) 产生后如何保护它们。我们可以像验证者在发送给证明者之前对s的指数进行加密一样对它们进行加密。然而,我们使用的同态加密不支持两个加密值的乘法,这对于验证检查以使t(s) 和h以及p和 α 的加密相乘都是必需的。这就是密码配对的地方。
密码配对(双线性映射)是一种数学构造,用函数 , 给定来自一组数字的两个加密输入(例如, ,允许将它们确定地映射到不同数字输出集中的乘法表示,即, 。
由于源和输出编号集合不同,因此配对的结果不能用作另一个配对操作的输入。我们可以将输出集 (也称为 “目标集”) 视为来自 “不同的宇宙”。因此,我们不能将结果乘以另一个加密值,并通过名称本身建议我们一次只能乘以两个加密值。在某种意义上,它类似于一个散列函数,它将所有可能的输入值映射到一组可能的输出值中的一个元素,并且它不是平凡可逆的。
注意: 乍一看,这种限制只能阻碍依赖的功能,具有讽刺意味的是,在zk-SNARK情况下,它是该方案的安全性所拥有的最重要的属性。
配对函数 的一个基本(技术上不正确)的数学类比是说明有一种方法可以“交换”每个输入的基数和指数,这样基数 在转换过程中会被修改成指数,例如 。 然后将两个“交换的”输入相乘,使得原始 a 和 b 值在相同的指数下相乘,例如:
因此,由于在“交换”期间使用结果 在另一个配对(例如, )中改变了碱基,因此不会产生所需的加密乘法 。配对的核心属性可以用等式表示:
e(ga, gb) = e(gb, ga) = e(gab, g1) = e(g1, gab) = e(g1, ga)b= e(g1, g1) ab= . . .
从技术上讲,配对的结果是目标集不同生成器g下原始值的加密产物,即 。因此,它具有同态加密的特性,例如,我们可以将多对的加密产物添加到一起:
注意:加密配对利用椭圆曲线来实现这些属性,因此从现在起,符号 将表示曲线上的生成器点,该点将被添加到自身 次,而不是我们在前面部分中使用的乘法群生成器。
有了加密配对,我们现在可以设置安全的公共和可重用参数。让我们假设我们信任一个诚实的一方来生成秘密 s 和 α。一旦 α 和具有相应 α 位移的 s 的所有必要幂被加密(gα, gsi , gαsi for i in 0, 1, ..., d),必须删除原始值。
这些参数通常被称为公共参考字符串common reference string或CRS。CRS生成后,任何prover和verifier都可以使用它来执行非交互式零知识证明协议。虽然不重要,但CRS的优化版本将包括对目标多项式target polynomial 的加密评估。
此外,CRS分为两组(对于 中的 ):
由于能够乘以加密值,verifier可以在协议的最后一步检查多项式,让verification key verifier进程从证明者那里接收到加密多项式评估 gp、gh、gp':
虽然可信设置是有效的,但它并不有效,因为 CRS 的多个用户将不得不相信一个删除的 和 ,因为目前没有办法证明这一点。 因此,有必要最小化或消除这种信任。 否则,不诚实的一方将能够在不被发现的情况下制作假证据。
实现这一点的一种方法是由多方使用前面部分中介绍的数学工具生成复合 CRS,这样这些方都不知道秘密。这是一种方法,让我们考虑三个参与者 Alice、Bob 和 Carol,对应的索引为 A、B 和 C,对于 i 在 1、2、...中。 . . , d:
作为这种协议的结果,我们有复合 和 并且没有参与者知道其他参与者的秘密参数,除非他们串通。事实上,为了学习 和 ,必须与其他所有参与者串通一气。因此,即使一个人是诚实的,也无法提供假证明。
注意:此过程可以根据需要对尽可能多的参与者重复。
可能存在的问题是如何验证参与者是否与 CRS 的每个值一致,因为对手可以采样多个不同的 s1、s2、...。 . . 和α1, α2, . . .,并将它们随机用于 s 的不同幂(或提供随机数作为增强的公共参考字符串),从而使 CRS 无效且不可用。
幸运的是,因为我们可以使用配对来乘以加密值,所以我们能够执行一致性检查,从第一个参数开始,并确保每个下一个参数都是从它派生的。参与者发布的每个 CRS 都可以检查如下:
请注意,虽然我们验证每个参与者都与他们的秘密参数一致,但使用先前发布的 CRS 的要求并未对每个下一个参与者强制执行(在我们的示例中为 Bob 和 Carol)。因此,如果对手是链中的最后一个,他可以忽略先前的 CRS 并从头开始构造有效参数,就好像他是链中的第一个,因此是唯一知道秘密 s 和 α 的人。
我们可以通过额外要求除第一个参与者之外的每个参与者加密和发布他的秘密参数来解决这个问题,例如,Bob 还发布:
这允许验证 Bob 的 CRS 是 Alice 参数的适当倍数,因为 i in 1, 2, . . . , d:
同样,Carol必须证明她的CRS是Alice-Bob的CRS的适当倍数。
这是一个强大的CRS设置方案,不完全依赖任何一方。实际上,即使只有一方是诚实的,并且删除并且从不共享其秘密参数,即使所有其他各方都合谋,它也是非常明智的。因此,CRS 设置中不相关的参与者越多,伪造证据的可能性就越小,如果竞争方参与,其可能性就可以忽略不计。该方案允许涉及对设置的易读性有疑问的其他不受信任的各方,因为验证步骤确保他们不会破坏最终的公共参考字符串 (也包括使用弱 α 和s)。
我们现在准备巩固进化的zk-SNARKOP协议。形式上,为简洁起见,我们将使用大括号来表示由其旁边的下标填充的一组元素,例如si i ∈[d] 表示集合s1,s2,...,sd。
已商定目标多项式t(x)和校准仪多项式的d次:
Setup:
F. 什么是ssl
ssl加密的方法
关键词: ssl加密的方法
随着计算机网络技术的发展,方便快捷的互连网使人们渐渐习惯了从Web页上收发E-mail、购物和
交易,这时Web页面上需要传输重要或敏感的数据,例如用户的银行帐户、密码等,所以网络安全
就成为现代计算机网络应用急需解决的问题。
现行网上银行和电子商务等大型的网上交易系统普遍采用HTTP和SSL相结合的方式。服务器端采用
支持SSL的Web服务器,用户端采用支持SSL的浏览器实现安全通信。
SSL是Secure Socket Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。
Netscape公司在推出第一个Web浏览器的同时,提出了SSL协议标准,目前已有3.0版本。SSL采用公
开密钥技术。其目标是保证两个应用间通信的保密性和可靠性,可在服务器端和用户端同时实现支
持。目前,利用公开密钥技术的SSL协议,已成为Internet上保密通讯的工业标准。本文着重在
SSL协议和SSL程序设计两方面谈谈作者对SSL的理解。
SSL协议初步介绍
安全套接层协议能使用户/服务器应用之间的通信不被攻击者窃听,并且始终对服务器进行认证,
还可选择对用户进行认证。SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于
它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于
SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证
工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。
通过以上叙述,SSL协议提供的安全信道有以下三个特性:
1.数据的保密性
信息加密就是把明码的输入文件用加密算法转换成加密的文件以实现数据的保密。加密的过程需要
用到密匙来加密数据然后再解密。没有了密钥,就无法解开加密的数据。数据加密之后,只有密匙
要用一个安全的方法传送。加密过的数据可以公开地传送。
2.数据的一致性
加密也能保证数据的一致性。例如:消息验证码(MAC),能够校验用户提供的加密信息,接收者可
以用MAC来校验加密数据,保证数据在传输过程中没有被篡改过。
3.安全验证
加密的另外一个用途是用来作为个人的标识,用户的密匙可以作为他的安全验证的标识。
SSL是利用公开密钥的加密技术(RSA)来作为用户端与服务器端在传送机密资料时的加密通讯协定。
目前,大部分的Web 服务器及浏览器都广泛支持SSL 技术。当浏览器试图连接一个具有SSL认证加
密的服务器时,就会唤醒一个SSL会话,浏览器检查认证,必须具备下面三个条件:
1)有一个权威机构发放证书,当然可以创建自我签订的证书(x509 结构)。
2)证书不能过期。
3)证书是属于它所连接的服务器的。
只有全部具备了这三个条件,浏览器才能成功完成认证。通过这三个条件,用户能确认其浏览器连接
到正确的服务器,而不是连接到一些想盗取用户密码等重要信息的虚假的服务器上。
在当今的电子商务中还有一项被广泛使用的安全协议是SET协议。SET(Secure Electronic Transaction,
安全电子交易)协议是由VISA和MasterCard两大信用卡公司于1997年5月联合推出的规范。SET能在电
子交易环节上提供更大的信任度、更完整的交易信息、更高的安全性和更少受欺诈的可能性。SET交
易分三个阶段进行:用户向商家购物并确定支付;商家与银行核实;银行向商家支付货款。每个阶段都
涉及到RSA对数据加密,以及RSA数字签名。使用SET协议,在一次交易中,要完成多次加密与解密操作,
故有很高的安全性,但SET协议比SSL协议复杂,商家和银行都需要改造系统以实现互操作。
在Linux 下,比较流行支持SSL认证的是OpenSSL服务器。OpenSSL项目是一个合作的项目,开发一个
健壮的、商业等级的、完整的开放源代码的工具包,用强大的加密算法来实现安全的Socket层
(Secure Sockets Layer,SSL v2/v3)和传输层的安全性(Transport Layer Security,TLS v1)。
这个项目是由全世界的志愿者管理和开发OpenSSL工具包和相关文档。
如何在Linux下配置OpenSSL服务器,首先从OpenSSL的主页(http://www.openssl.org/)上下载
openssl-version.tar.gz软件包来编译安装,与Apache服务器配合可以建立支持SSL的Web服务器,
并可以使用自我签订的证书做认证,关于如何编译、安装OpenSSL服务器,可以参考一下OpenSSL HOWTO
文档。
SSL 程序设计初步介绍
SSL 通讯模型为标准的C/S 结构,除了在 TCP 层之上进行传输之外,与一般的通讯没有什么明显的区
别。在这里,我们主要介绍如何使用OpenSSL进行安全通讯的程序设计。关于OpenSSL 的一些详细的信
息请参考OpenSSL的官方主页 http://www.openssl.org。
在使用OpenSSL前,必须先对OpenSSL 进行初始化,以下的三个函数任选其一:
SSL_library_init(void);
OpenSSL_add_ssl_algorithms();
SSLeay_add_ssl_algorithms();
事实上 后面的两个函数只是第一个函数的宏。
如果要使用OpenSSL的出错信息,使用SSL_load_error_strings (void)进行错误信息的初始化。以后
可以使用void ERR_print_errors_fp(FILE *fp) 打印SSL的错误信息。
一次SSL连接会话一般要先申请一个SSL 环境,基本的过程是:
1. SSL_METHOD* meth = TLSv1_client_method(); 创建本次会话连接所使用的协议,如果是客户端可
以使用
SSL_METHOD* TLSv1_client_method(void); TLSv1.0 协议
SSL_METHOD* SSLv2_client_method(void); SSLv2 协议
SSL_METHOD* SSLv3_client_method(void); SSLv3 协议
SSL_METHOD* SSLv23_client_method(void); SSLv2/v3 协议
服务器同样需要创建本次会话所使用的协议:
SSL_METHOD *TLSv1_server_method(void);
SSL_METHOD *SSLv2_server_method(void);
SSL_METHOD *SSLv3_server_method(void);
SSL_METHOD *SSLv23_server_method(void);
需要注意的是客户端和服务器需要使用相同的协议。
2.申请SSL会话的环境 CTX,使用不同的协议进行会话,其环境也是不同的。申请SSL会话环
境的OpenSSL函数是
SSLK_CTX* SSL_CTX_new (SSL_METHOD*); 参数就是前面我们申请的 SSL通讯方式。返回当前
的SSL 连接环境的指针。
然后根据自己的需要设置CTX的属性,典型的是设置SSL 握手阶段证书的验证方式和加载自己
的证书。
void SSL_CTX_set_verify (SSL_CTX* , int , int* (int, X509_STORE_CTX*) )
设置证书验证的方式。
第一个参数是当前的CTX 指针,第二个是验证方式,如果是要验证对方的话,就使用
SSL_VERIFY_PEER。不需要的话,使用SSL_VERIFY_NONE.一般情况下,客户端需要验证对方,而
服务器不需要。第三个参数是处理验证的回调函数,如果没有特殊的需要,使用空指针就可以了。
void SSL_CTX_load_verify_locations(SSL_CTX*, const char* , const char*);
加载证书;
第一个参数同上,参数二是证书文件的名称,参数三是证书文件的路径;
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
加载本地的证书;type 指明证书文件的结构类型;失败返回-1
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
加载自己的私钥;type 参数指明私钥文件的结构类型;失败返回-1
加载了证书和文件之后,就可以验证私钥和证书是否相符:
BOOl SSL_CTX_check_private_key (SSL_CTX*);
3.既然SSL 使用TCP 协议,当然需要把SSL attach 到已经连接的套接字上了:
SSL* SSL_new (SSL_CTX*); 申请一个SSL 套节字;
int SSL_set_rfd (SSL*); 绑定只读套接字
int SSL_set_wfd (SSL*); 绑定只写套接字
int SSL_set_fd ( SSL*); 绑定读写套接字
绑定成功返回 1, 失败返回0;
4. 接下来就是SSL 握手的动作了
int SSL_connect (SSL*); 失败返回 -1
5. 握手成功之后,就可以进行通讯了,使用SSL_read 和SS_write 读写SSL 套接字代替传统的
read 、write
int SSL_read (SSL *ssl, char *buf, int num );
int SSL_write (SSL *ssl, char *buf, int num);
如果是服务器,则使用 SSL_accept 代替传统的 accept 调用
int SSL_accept(SSL *ssl);
6. 通讯结束,需要释放前面申请的 SSL资源
int SSL_shutdown(SSL *ssl); 关闭SSL套接字;
void SSL_free (ssl); 释放SSL套接字;
void SSL_CTX_free (ctx); 释放SSL环境;
OpenSSL 虽然已经发展到了0.9.96版本,但是它的文档还很少,甚至连最基本的man 函数手
册都没有完成。所以,本文紧紧是讲述了使用OpenSSL 进行程序设计的框架。更加详细的资
料可以参考OpenSSL 的文档或者 Apache mod_ssl 的文档。
通过以上的介绍,我想读者对SSL协议已经有了一定的了解,作者有机会将会继续给大家介绍
SSL协议的其他方面的内容。
SSL原理解密
本文出自:
http://noc.cstnet.net.cn/
范晓明
RSA公钥加密在计算机产业中被广泛使用在认证和加密。可以从RSA Data Security Inc.获得的RSA公钥加密许可证。公钥加密是使用一对非对称的密码加密或解密的方法。每一对密码由公钥和私钥组成。公钥被广泛发布。私钥是隐密的,不公开。用公钥加密的数据只能够被私钥解密。反过来,使用私钥加密的数据只能用公钥解密。这个非对称的特性使得公钥加密很有用。
使用公钥加密法认证
认证是一个身份认证的过程。在下列例子中包括甲和乙,公钥加密会非常轻松地校验身份。符号{数据} key意味着"数据"已经使用密码加密或解密。假如甲想校验乙的身份。乙有一对密码,一个是公开的,另一个是私有的。乙透露给甲他的公钥。甲产生一个随机信息发送给乙。甲——〉乙:random-message
乙使用他的私钥加密消息,返回甲加密后的消息。 乙——〉甲:{random-message}乙的私钥
甲收到这个消息然后使用乙的以前公开过的公钥解密。他比较解密后的消息与他原先发给乙的消息。如果它们完全一致,就会知道在与乙说话。任意一个中间人不会知道乙的私钥,也不能正确加密甲检查的随机消息。
除非你清楚知道你加密的消息。用私钥加密消息,然后发送给其他人不是一个好主意。因为加密值可能被用来对付你,需要注意的是:因为只有你才有私钥,所以只有你才能加密消息。所以,代替加密甲发来的原始消息,乙创建了一个信息段并且加密。信息段取自随机消息(random-message)并具有以下有用的特性:
1. 这个信息段难以还原。任何人即使伪装成乙,也不能从信息段中得到原始消息;
2. 假冒者将发现不同的消息计算出相同的信息段值;
3. 使用信息段,乙能够保护自己。他计算甲发出的随机信息段,并且加密结果,并发送加密信息段返回甲。甲能够计算出相同的信息段并且解密乙的消息认证乙。
这个技术仅仅描绘了数字签名。通过加密甲产生的随机消息,乙已经在甲产生的消息签名。因此我们的认证协议还需要一次加密。一些消息由乙产生:
甲——〉乙:你好,你是乙么?
乙——〉甲:甲,我是乙
{信息段[甲,我是乙] } 乙的私钥
当你使用这个协议,乙知道他发送给乙的消息,他不介意在上面签名。他先发送不加密的信息,"甲,我是乙。",然后发送信息段加密的消息版本。甲可以非常方便地校验乙就是乙,同时,乙还没有在他不想要的信息上签名。
提交公钥
那么,乙怎样以可信的方式提交他的公钥呢?看看认证协议如下所示:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的公钥
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] } 乙的私钥
在这个协议下,任何人都能够成为"乙"。所有你所要的只是公钥和私钥。你发送给甲说你就是乙,这样你的公钥就代替了乙的密码。然后,你发送用你的私钥加密的消息,证明你的身份。甲却不能发觉你并不是乙。为了解决这个问题,标准组织已经发明了证书。一个证书有以下的内容:
* 证书的发行者姓名
* 发行证书的组织
* 标题的公钥
* 邮戳
证书使用发行者的私钥加密。每一个人都知道证书发行者的公钥(这样,每个证书的发行者拥有一个证书)。证书是一个把公钥与姓名绑定的协议。通过使用证书技术,每一个人都可以检查乙的证书,判断是否被假冒。假设乙控制好他的私钥,并且他确实是得到证书的乙,就万事大吉了。
这些是修订后的协议:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校验
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲, 我是乙] } 乙的私钥
现在当甲收到乙的第一个消息,他能检查证书,签名(如上所述,使用信息段和公钥解密),然后检查标题(乙的姓名),确定是乙。他就能相信公钥就是乙的公钥和要求乙证明自己的身份。乙通过上面的过程,制作一个信息段,用一个签名版本答复甲。甲可以校验乙的信息段通过使用从证书上得到的公钥并检查结果。
如果一个黑客,叫H
甲——〉H:你好
H——〉不能建立一个令甲相信的从乙的消息。
交换密码(secret)
一旦甲已经验证乙后,他可以发送给乙一个只有乙可以解密、阅读的消息:
甲——〉乙:{secret}乙的公钥
唯一找到密码的方法只有使用乙的私钥解码上述的信息。交换密码是另一个有效使用密码加密的方法。即使在甲和乙之间的通讯被侦听,只有乙才能得到密码。
使用密码作为另一个secret-key增强了网络的安全性,但是这次这是一个对称的加密算法(例如DES、RC4、IDE甲)。因为甲在发送给乙之前产生了密码,所以甲知道密码。乙知道密码因为乙有私钥,能够解密甲的信息。但他们都知道密码,他们都能够初始化一个对称密码算法,而且开始发送加密后的信息。这儿是修定后的协议:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校验
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私钥
甲——〉乙:ok 乙,here is a secret {secret}乙的公钥
乙——〉甲:{some message}secret-key
黑客窃听
那么如果有一个恶意的黑客H在甲和乙中间,虽然不能发现甲和乙已经交换的密码,但能干扰他们的交谈。他可以放过大部分信息,选择破坏一定的信息(这是非常简单的,因为他知道甲和乙通话采用的协议)。
甲——〉H:你好
H——〉乙:你好
乙——〉H:嗨,我是乙,乙的校验
H——〉甲:嗨,我是乙,乙的校验
甲——〉H:prove it
H——〉乙:prove it
乙——〉H:甲,我是乙 {信息段[甲,我是乙] }乙的私钥
H——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私钥
甲——〉H:ok 乙,here is a secret {secret} 乙的公钥
H——〉乙:ok 乙,here is a secret {secret} 乙的公钥
乙——〉H:{some message}secret-key
H——〉甲:Garble[{some message}secret-key ]
H忽略一些数据不修改,直到甲和乙交换密码。然后H干扰乙给甲的信息。在这一点上,甲相信乙,所以他可能相信已经被干扰的消息并且尽力解密。
需要注意的是,H不知道密码,他所能做的就是毁坏使用秘钥加密后的数据。基于协议,H可能不能产生一个有效的消息。但下一次呢?
为了阻止这种破坏,甲和乙在他们的协议中产生一个校验码消息(message authentication code)。一个校验码消息(MAC)是一部分由密码和一些传输消息产生的数据。信息段算法描述的上述特性正是它们抵御H的功能:
MAC= Digest[some message,secret ]
因为H不知道密码,他不能得出正确的值。即使H随机干扰消息,只要数据量大,他成功的机会微乎其微。例如,使用HD5(一个RSA发明的好的加密算法),甲和乙能够发送128位MAC值和他们的消息。H猜测正确的MAC的几率将近1/18,446,744,073,709,551,616约等于零。
这是又一次修改后的协议:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校验
甲——〉乙:prove it
乙——〉甲:嗨,我是乙,乙的校验
甲,我是乙
{信息段[甲,我是乙] } 乙的私钥
ok 乙,here is a secret {secret} 乙的公钥
{some message,MAC}secret-key
现在H已经无技可施了。他干扰了得到的所有消息,但MAC计算机能够发现他。甲和乙能够发现伪造的MAC值并且停止交谈。H不再能与乙通讯。
OpenSSL FAQ