导航:首页 > 源码编译 > 下列不属于ec算法密钥长度的是

下列不属于ec算法密钥长度的是

发布时间:2023-04-06 16:00:25

① AES加密算法支持密钥key为多少位的

严格地说,AES和Rijndael加密法并不完全一样(虽然在实际应用中二者可以互换),因为Rijndael加密法可以支罩闹持更大范围的区块和密钥长度:

AES的区块长度固定为128位,密钥长度则可以是128,192或256位;而Rijndael使用的密钥和区块长度可以是32位的整数倍,以128位为下限,256位为上限。加密过程中使用的密钥是由Rijndael密钥生成方案产生。

(1)下列不属于ec算法密钥长度的是扩展阅读

AES加密模式

对称/分组密码一般分为流加密(如OFB、CFB等)和块加密(如ECB、CBC等)。对于流加密,需要将分组密码转化为流模式工作。对于块加密(或称分组加密),如果要加密超过块大小的数据,就需要涉及填充和链加物凳罩密模式。

优点:

1、简单;

2、有利于并行计算;

3、误差不会被传送;

缺点:

1、不能隐藏明文的模式;

2、可能对明文进行主动粗键攻击;

3、因此,此模式适于加密小消息。

② ¥¥¥¥基于java语言的数字签名¥¥¥¥¥

毕业设计起码也得2个月时间,你现在才开始,不复制粘贴来不及啊~

Java加密和数字签名编程快速入门

本文主要谈一下密码学中的加密和数字签名,以及其在java中如何进行使用。对密码学有兴趣的伙伴,推荐看Bruce Schneier的着作:Applied Crypotography。在jdk1.5的发行版本中安全性方面有了很大的改进,也提供了对RSA算法的直接支持,现在我们从实例入手解决问题(本文仅是作为简单介绍):

一、密码学上常用的概念

1)消息摘要:

这是一种与消息认证码结合使用以确保消息完整性的技术。主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,目前广泛使用的算法有MD4、MD5、SHA-1,jdk1.5对上面都提供了支持,在java中进行消息摘要很简单, java.security.MessageDigest提供了一个简易的操作方法:

/**
*MessageDigestExample.java
*Copyright 2005-2-16
*/
import java.security.MessageDigest;
/**
*单一的消息摘要算法,不使用密码.可以用来对明文消息(如:密码)隐藏保存
*/
public class MessageDigestExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java MessageDigestExample text");
System.exit(1);
}

byte[] plainText=args[0].getBytes("UTF8");

//使用getInstance("算法")来获得消息摘要,这里使用SHA-1的160位算法
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");

System.out.println("\n"+messageDigest.getProvider().getInfo());
//开始使用算法
messageDigest.update(plainText);
System.out.println("\nDigest:");
//输出算法运算结果
System.out.println(new String(messageDigest.digest(),"UTF8"));
}
}

还可以通过消息认证码来进行加密实现,javax.crypto.Mac提供了一个解决方案,有兴趣者可以参考相关API文档,本文只是简单介绍什么是摘要算法。

2)私钥加密:

消息摘要只能检查消息的完整性,但是单向的,对明文消息并不能加密,要加密明文的消息的话,就要使用其他的算法,要确保机密性,我们需要使用私钥密码术来交换私有消息。

这种最好理解,使用对称算法。比如:A用一个密钥对一个文件加密,而B读取这个文件的话,则需要和A一样的密钥,双方共享一个私钥(而在web环境下,私钥在传递时容易被侦听):

使用私钥加密的话,首先需要一个密钥,可用javax.crypto.KeyGenerator产生一个密钥(java.security.Key),然后传递给一个加密工具(javax.crypto.Cipher),该工具再使用相应的算法来进行加密,主要对称算法有:DES(实际密钥只用到56位),AES(支持三种密钥长度:128、192、256位),通常首先128位,其他的还有DESede等,jdk1.5种也提供了对对称算法的支持,以下例子使用AES算法来加密:

/**
*PrivateExmaple.java
*Copyright 2005-2-16
*/
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;

/**
*私鈅加密,保证消息机密性
*/
public class PrivateExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PrivateExample <text>");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");

//通过KeyGenerator形成一个key
System.out.println("\nStart generate AES key");
KeyGenerator keyGen=KeyGenerator.getInstance("AES");
keyGen.init(128);
Key key=keyGen.generateKey();
System.out.println("Finish generating DES key");

//获得一个私鈅加密类Cipher,ECB是加密方式,PKCS5Padding是填充方法
Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
System.out.println("\n"+cipher.getProvider().getInfo());

//使用私鈅加密
System.out.println("\nStart encryption:");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));

System.out.println("\nStart decryption:");
cipher.init(Cipher.DECRYPT_MODE,key);
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");

System.out.println(new String(newPlainText,"UTF8"));

}
}

3)公钥加密:

上面提到,私钥加密需要一个共享的密钥,那么如何传递密钥呢?web环境下,直接传递的话很容易被侦听到,幸好有了公钥加密的出现。公钥加密也叫不对称加密,不对称算法使用一对密钥对,一个公钥,一个私钥,使用公钥加密的数据,只有私钥能解开(可用于加密);同时,使用私钥加密的数据,只有公钥能解开(签名)。但是速度很慢(比私钥加密慢100到1000倍),公钥的主要算法有RSA,还包括Blowfish,Diffie-Helman等,jdk1.5种提供了对RSA的支持,是一个改进的地方:

/**
*PublicExample.java
*Copyright 2005-2-16
*/
import java.security.Key;
import javax.crypto.Cipher;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
/**
*一个简单的公鈅加密例子,Cipher类使用KeyPairGenerator生成的公鈅和私鈅
*/
public class PublicExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PublicExample <text>");
System.exit(1);
}

byte[] plainText=args[0].getBytes("UTF8");
//构成一个RSA密钥
System.out.println("\nStart generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");

//获得一个RSA的Cipher类,使用公鈅加密
Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
System.out.println("\n"+cipher.getProvider().getInfo());

System.out.println("\nStart encryption");
cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));

//使用私鈅解密
System.out.println("\nStart decryption");
cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}

4)数字签名:

数字签名,它是确定交换消息的通信方身份的第一个级别。上面A通过使用公钥加密数据后发给B,B利用私钥解密就得到了需要的数据,问题来了,由于都是使用公钥加密,那么如何检验是A发过来的消息呢?上面也提到了一点,私钥是唯一的,那么A就可以利用A自己的私钥进行加密,然后B再利用A的公钥来解密,就可以了;数字签名的原理就基于此,而通常为了证明发送数据的真实性,通过利用消息摘要获得简短的消息内容,然后再利用私钥进行加密散列数据和消息一起发送。java中为数字签名提供了良好的支持,java.security.Signature类提供了消息签名:

/**
*DigitalSignature2Example.java
*Copyright 2005-2-16
*/
import java.security.Signature;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.SignatureException;

/**
*数字签名,使用RSA私钥对对消息摘要签名,然后使用公鈅验证 测试
*/
public class DigitalSignature2Example{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java DigitalSignature2Example <text>");
System.exit(1);
}

byte[] plainText=args[0].getBytes("UTF8");
//形成RSA公钥对
System.out.println("\nStart generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);

KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//使用私鈅签名
Signature sig=Signature.getInstance("SHA1WithRSA");
sig.initSign(key.getPrivate());
sig.update(plainText);
byte[] signature=sig.sign();
System.out.println(sig.getProvider().getInfo());
System.out.println("\nSignature:");
System.out.println(new String(signature,"UTF8"));

//使用公鈅验证
System.out.println("\nStart signature verification");
sig.initVerify(key.getPublic());
sig.update(plainText);
try{
if(sig.verify(signature)){
System.out.println("Signature verified");
}else System.out.println("Signature failed");
}catch(SignatureException e){
System.out.println("Signature failed");
}
}
}

5)数字证书。

还有个问题,就是公钥问题,A用私钥加密了,那么B接受到消息后,用A提供的公钥解密;那么现在有个讨厌的C,他把消息拦截了,然后用自己的私钥加密,同时把自己的公钥发给B,并告诉B,那是A的公钥,结果....,这时候就需要一个中间机构出来说话了(相信权威,我是正确的),就出现了Certificate Authority(也即CA),有名的CA机构有Verisign等,目前数字认证的工业标准是:CCITT的X.509:
数字证书:它将一个身份标识连同公钥一起进行封装,并由称为认证中心或 CA 的第三方进行数字签名。

密钥库:java平台为你提供了密钥库,用作密钥和证书的资源库。从物理上讲,密钥库是缺省名称为 .keystore 的文件(有一个选项使它成为加密文件)。密钥和证书可以拥有名称(称为别名),每个别名都由唯一的密码保护。密钥库本身也受密码保护;您可以选择让每个别名密码与主密钥库密码匹配。

使用工具keytool,我们来做一件自我认证的事情吧(相信我的认证):

1、创建密钥库keytool -genkey -v -alias feiUserKey -keyalg RSA 默认在自己的home目录下(windows系统是c:\documents and settings\<你的用户名> 目录下的.keystore文件),创建我们用 RSA 算法生成别名为 feiUserKey 的自签名的证书,如果使用了-keystore mm 就在当前目录下创建一个密钥库mm文件来保存密钥和证书。

2、查看证书:keytool -list 列举了密钥库的所有的证书

也可以在dos下输入keytool -help查看帮助。

二、JAR的签名

我们已经学会了怎样创建自己的证书了,现在可以开始了解怎样对JAR文件签名,JAR文件在Java中相当于 ZIP 文件,允许将多个 Java 类文件打包到一个具有 .jar 扩展名的文件中,然后可以对这个jar文件进行数字签名,以证实其来源和真实性。该 JAR 文件的接收方可以根据发送方的签名决定是否信任该代码,并可以确信该内容在接收之前没有被篡改过。同时在部署中,可以通过在策略文件中放置访问控制语句根据签名者的身份分配对机器资源的访问权。这样,有些Applet的安全检验访问就得以进行。

使用jarsigner工具可以对jar文件进行签名:

现在假设我们有个Test.jar文件(可以使用jar命令行工具生成):

jarsigner Test.jar feiUserKey (这里我们上面创建了该别名的证书) ,详细信息可以输入jarsigner查看帮助

验证其真实性:jarsigner -verify Test.jar(注意,验证的是jar是否被修改了,但不检验减少的,如果增加了新的内容,也提示,但减少的不会提示。)

使用Applet中:<applet code="Test.class" archive="Test.jar" width="150" height="100"></applet>然后浏览器就会提示你:准许这个会话-拒绝-始终准许-查看证书等。

三、安全套接字层(SSL Secure Sockets Layer)和传输层安全性(TLS Transport Layer Security)

安全套接字层和传输层安全性是用于在客户机和服务器之间构建安全的通信通道的协议。它也用来为客户机认证服务器,以及(不太常用的)为服务器认证客户机。该协议在浏览器应用程序中比较常见,浏览器窗口底部的锁表明 SSL/TLS 有效:

1)当使用 SSL/TLS(通常使用 https:// URL)向站点进行请求时,从服务器向客户机发送一个证书。客户机使用已安装的公共 CA 证书通过这个证书验证服务器的身份,然后检查 IP 名称(机器名)与客户机连接的机器是否匹配。

2)客户机生成一些可以用来生成对话的私钥(称为会话密钥)的随机信息,然后用服务器的公钥对它加密并将它发送到服务器。服务器用自己的私钥解密消息,然后用该随机信息派生出和客户机一样的私有会话密钥。通常在这个阶段使用 RSA 公钥算法。

3)客户机和服务器使用私有会话密钥和私钥算法(通常是 RC4)进行通信。使用另一个密钥的消息认证码来确保消息的完整性。

java中javax.net.ssl.SSLServerSocketFactory类提供了一个很好的SSLServerSocker的工厂类,熟悉Socket编程的读者可以去练习。当编写完服务器端之后,在浏览器上输入https://主机名:端口 就会通过SSL/TLS进行通话了。注意:运行服务端的时候要带系统环境变量运行:javax.net.ssl.keyStore=密钥库(创建证书时,名字应该为主机名,比如localhost)和javax.net.ssl.keyStorePassword=你的密码

③ 快速了解常用的对称加密算法,再也不用担心面试官的刨根问底

加密算法通常被分为两种: 对称加密 非对称加密 。其中,对称加密算法在加密和解密时使用的密钥相同;非对称加密算法在加密和解密时使用的密钥不同,分为公钥和私钥。此外,还有一类叫做 消息摘要算法 ,是对数据进行摘要并且不可逆的算法。

这次我们了解一下对称加密算法。

对称加密算法在加密和解密时使用的密钥相同,或是使用两个可以简单地相互推算的密钥。在大多数的对称加密算法中,加密和解密的密钥是相同的。

它要求双方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送的信息进行解密,这也是对称加密算法的主要缺点之一。

常见的对称加密算法有:DES算法、3DES算法、AES算法。

DES算法(Data Encryption Standard)是一种常见的分组加密算法。

分组加密算法是将明文分成固定长度的组,每一组都采用同一密钥和算法进行加密,输出也是固定长度的密文。

由IBM公司在1972年研制,1976年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),随后在国际上广泛流传开来。

在DES算法中,密钥固定长度为64位。明文按64位进行分组,分组后的明文组和密钥按位置换或交换的方法形成密文组,然后再把密文组拼装成密文。

密钥的每个第八位设置为奇偶校验位,也就是第8、16、24、32、40、48、56、64位,所以密钥的实际参与加密的长度为56位。

我们用Java写个例子:

运行结果如下:

DES现在已经不是一种安全的加密方法,主要因为它使用的密钥过短,很容易被暴力破解。

3DES算法(Triple Data Encryption Algorithm)是DES算法的升级版本,相当于是对明文进行了三次DES加密。

由于计算机运算能力的增强,DES算法由于密钥长度过低容易被暴力破解;3DES算法提供了一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

在DES算法中,密钥固定长度为192位。在加密和解密时,密钥会被分为3个64位的密钥。

加密过程如下:

解密过程如下:

我们用Java写个例子:

运行结果如下:

虽然3DES算法在安全性上有所提升,但是因为使用了3次DES算法,加密和解密速度比较慢。

AES(Advanced Encryption Standard,高级加密标准)主要是为了取代DES加密算法的,虽然出现了3DES的加密方法,但由于它的加密时间是DES算法的3倍多,密钥位数还是不能满足对安全性的要求。

1997年1月2号,美国国家标准与技术研究院(NIST)宣布什望征集高级加密标准,用以取代DES。全世界很多密码工作者都提交了自己设计的算法。经过甄选流程,高级加密标准由美国国家标准与技术研究院于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。

该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以 Rijndael 为名投稿高级加密标准的甄选流程。

AES算法的密钥长度是固定,密钥的长度可以使用128位、192位或256位。

AES算法也是一种分组加密算法,其分组长度只能是128位。分组后的明文组和密钥使用几种不同的方法来执行排列和置换运算形成密文组,然后再把密文组拼装成密文。

我们用Java写个例子:

运行结果如下:

AES算法是目前应用最广泛的对称加密算法。

对称加密算法在加密和解密时使用的密钥相同,常见的对称加密算法有:DES算法、3DES算法、AES算法。
由于安全性低、加密解密效率低,DES算法和3DES算法是不推荐使用的,AES算法是目前应用最广泛的对称加密算法。

④ 密码技术(十一)之密钥

  ——秘密的精华

 在使用对称密码、公钥密码、消息认证码、数字签名等密码技术使用,都需要一个称为 密钥 的巨大数字。然而,数字本身的大小并不重要,重要的是 密钥空间的大小 ,也就是可能出现的密钥的总数量,因为密钥空间越大,进行暴力破解就越困难。密钥空间的大小是由 密钥长度 决定的。

 对称密码DES的密钥的实质长度为56比特(7个字节)。
例如,
一个DES密钥用二进制可以表示为:
01010001 11101100 01001011 00010010 00111101 01000010 00000011
用十六进制则可以表示为:
51 EC 4B 12 3D 42 03
而用十进制则可以表示为:
2305928028626269955

 在对称密码三重DES中,包括使用两个DES密钥的DES-EDE2和使用三个DES密钥的DES-EDE3这两种方式。
DES-EDE2的密钥长度实质长度为112比特(14字节),比如:
51 EC 4B 12 3D 42 03 30 04 D8 98 95 93 3F
DES-EDE3的密钥的实质长度为168比特(21字节),比如:
51 EC 4B 12 3D 42 03 30 04 D8 98 95 93 3F 24 9F 61 2A 2F D9 96

 对称密码AES的密钥长度可以从128、192和256比特中进行选择,当密钥长度为256比特时,比如:
51 EC 4B 12 3D 42 03 30 04 D8 98 95 93 3F 24 9F 61 2A 2F D9 96
B9 42 DC FD A0 AE F4 5D 60 51 F1

密钥和明文是等价的 。假设明文具有100万的价值,那么用来加密这段明文的密钥也就是具有100万元的价值;如果明文值1亿元,密钥也就值1亿元;如果明文的内容是生死攸关的,那么密钥也同样是生死攸关的。

 在对称密码中,加密和解密使用同一个密钥。由于发送者和接收者需要共享密钥,因此对称密码又称为共享密钥密码。对称密码中所使用的密钥必须对发送者和接收者以外的人保密,否则第三方就能够解密了。

 在消息认证码中,发送者和接收者使用共享的密钥来进行认证。消息认证码只能由持有合法密钥的人计算出来。将消息认证码附加在通信报文后面,就可以识别通信内容是否被篡改或伪装,由于“持有合法的密钥”就是发送者和接收者合法身份的证明,因此消息认证码的密钥必须对发送者以外的人保密,否则就会产生篡改和伪装的风险。

 在数字签名中,签名生成和验证使用不同的密钥,只有持有私钥的本人才能够生成签名,但由于验证签名使用的是公钥,因此任何人都能够验证签名。

 对称密码和公钥密码的密钥都是用于确保机密性的密钥。如果不知道用于解密的合法密钥,就无法得知明文的内容。
 相对地,消息认证码和数字签名所使用的密钥,则是用于认证的密钥。如果不知道合法的密钥,就无法篡改数据,也无法伪装本人的身份。

 当我们访问以https://开头的网页时,Web服务器和浏览器之间会进行基于SSL/TLS的加密通信。在这样的通信中所使用的密钥是仅限于本次通信的一次密钥,下次通信时就不能使用了,想这样每次通信只能使用一次的密钥称为 会话密钥
 由于会话密钥只在本次通信中有效,万一窃听者获取了本次通信的会话密钥,也只能破译本次通信的内容。
 虽然每次通信都会更换会话密钥,但如果用来生成密钥的伪随机数生成器品质不好,窃听者就有可能预测出下次生成会话密钥,这样就会产生通信内容被破译的风险。
 相对于每次通信更换的会话密钥,一直被重复使用的密钥称为 主密钥

 一般来说,加密的对象是用户直接使用的信息,这样的情况下所使用的密钥称为CEK(Contents Encryting Key,内容加密密钥);相对地,用于加密密钥的密钥则称为KEK(Key Encryting Key,密钥加密密钥)。

 在很多情况下,之前提到的会话密钥都是被作为CEK使用的,而主密钥则是被作为KEK使用的。

 生成密钥的最好方法就是使用随机数,因为米哟啊需要具备不易被他人推测的性质。在可能的情况下最好使用能够生成密码学上的随机数的硬件设备,但一般我们都是使用伪随机数生成器这一专门为密码学用途设计的软件。
 在生成密钥时,不能自己随便写出一些像“3F 23 52 28 E3....”这样的数字。因为尽管你想生成的是随机的数字,但无论如何都无法避免人为偏差,而这就会成为攻击者的目标。
 尽管生成伪随机数的算法有很多种,但密码学用途伪随机生成器必须是专门针对密码学用途而设计的。例如,有一些伪随机数生成器可以用于游戏和模拟算法,尽管这些伪随机数生成器所生成的数列看起也是随机的,但只要不是专门为密码学用途设计的,就不能用来生成密钥,因为这些伪随机数生成器不具备不可预测性这一性质。

 有时候我们也会使用人类的可以记住的口令(pasword或passphrase)来生成密钥。口令指的是一种由多个单词组成的较长的password。
 严格来说,我们很少直接使用口令来作为密钥使用,一般都是将口令输入单向散列函数,然后将得到的散列值作为密钥使用。
 在使用口令生成密钥时,为了防止字典攻击,需要在口令上附加一串称为盐(salt)的随机数,然后在将其输入单向散列函数。这种方法称为“基于口令的密码(Password Based Encryption,PBE)”。

 在使用对称密码时,如何在发送者和接收者之间共享密钥是一个重要的问题,要解决密钥配送问题,可以采用事先共享密钥,使用密钥分配中心,使用公钥密码等方法,除了上述方法,之前还提到一种解决密钥配送的问题的方法称为Diffie-Hellman密钥交换。

 有一种提供通信机密性的技术称为 密钥更新 (key updating),这种方法就是在使用共享密钥进行通信的过程中,定期更改密钥。当然,发送者和接收者必须同时用同样的方法来改变密钥才行。
 在更新密钥时,发送者和接收者使用单向散列函数计算当前密钥的散列值,并将这个散列值用作新的密钥。简单说,就是 用当前密钥散列值作为下一个密钥
 我们假设在通信过程中的某个时间点上,密钥被窃听者获取了,那么窃听者就可以用这个密钥将之后的通信内容全部解密。但是,窃听者却无法解密更新密钥这个时间点之前的内容,因为这需要用单向散列函数的输出反算出单向散列函数的输入。由于单向散列函数具有单向性,因此就保证了这样的反算是非常困难的。
 这种防止破译过去的通信内容机制,称为 后向安全 (backward security)。

 由于会话密钥在通信过程中仅限于一次,因此我们不需要保存这种秘密。然而,当密钥需要重复使用时,就必须要考虑保存密钥的问题了。

 人类是 无法记住具有实用长度的密钥 的。例如,像下面这样一个AES的128比特的密钥,一般人是很难记住的。
51 EC 4B 12 3D 42 03 30 04 DB 98 95 93 3F 24 9F
就算勉强记住了,也只过不是记住一个密钥而已。但如果要记住多个像这样的密钥并且保证不忘记,实际上是非常困难的。

 我们记不住密钥,但如果将密钥保存下来又可能会被窃取。这真是一个头疼的问题。这个问题很难得到彻底解决,但我们可以考虑一些合理的解决方法。
 将密钥保存生文件,并将这个文件保存在保险柜等安全地方。但是放在保险柜里的话,出门就无法使用了。这种情况,出门时就需要随身携带密钥。而如果将密钥放在存储卡随身携带的话,就会产生存储卡丢失、被盗等风险。
 万一密钥被盗,为了能够让攻击者花更多的时间才能真正使用这个密钥,我们可以使用将密钥加密后保存的方法,当然,要将密钥加密,必须需要另一个密钥。像这样用于密码加密的密钥,一般称为KEK。
 对密钥进行加密的方法虽然没有完全解决机密性的问题,但在现实中却是一个非常有效地方法,因为这样做可以减少需要保管密钥的数量。
 假设计算机上有100万个文件,分别使用不同的密钥进行加密生成100万个密文,结果我们手上就产生了100万个密钥,而要保管100万个密钥是很困难的。
 于是,我们用一个密钥(KEK)将这100万个密钥进行加密,那么现在我们只要保管者一个KEK就可以了,这一个KEK的价值相当于签名的100万个密钥的价值的总和。
 用1个密钥来代替多个密钥进行保管的方法,和认证机构的层级化非常相似。在后者中,我们不需要信任多个认证机构,而只需要信任一个根CA就可以了。同样的,我们也不需要确保多个密钥的机密性,而只需要确保一个KEK的机密性就可以了。

 密钥的作废和生成是同等重要的,这是因为密钥和明文是等价的。

 假设Alice向Bob发送了一封加密邮件。Bob在解密之后阅读了邮件的内容,这时本次通信所使用的密钥对于Alice和Bob来说就不需要了。不在需要的密钥必须妥善删除,因为如果被窃听者Eve获取,之前发送的加密邮件就会被解密。

 如果密钥是计算机上的一个文件,那么仅仅删除这个文件是不足以删除密钥的,因为有一些技术能够让删除的文件“恢复”。此外,很多情况下文件的内容还会残留在计算机的内存中,因此必须将这些痕迹完全抹去。简而言之,要完全删除密钥,不但要用到密码软件,还需要在设计计算机系统时对信息安全进行充分的考虑

 如果包含密钥的文件被误删或者保管密钥的笔记本电脑损坏了,会怎么样?
 如果丢失了对称密钥密码的共享密钥,就无法解密密文了。如果丢失了消息认证码的密钥,就无法向通信对象证明自己的身份了。
 公钥密码中,一般不太会发送丢失公钥的情况,因为公钥是完全公开的,很有可能在其他电脑上存在副本。
 最大的问题是丢失公钥密码的私钥。如果丢失了公钥密码的私钥,就无法解密用公钥密码加密的密文了。此外,如果丢失了数字签名的私钥,就无法生成数字签名了。

 Diffie-Hellman密钥交换(Diffie-Hellman key exchange)是1976年由Whitfield Diffie和Martin Hellman共同发明的一种算法。使用这种算法,通信双方仅通过交换一些可以公开的信息就能够生成共享秘密数字,而这一秘密数字就可以被用作对称密码的密钥。IPsec 中就使用了经过改良的Diffie-Hellman密钥交换。

2 Alice 生成一个随机数A
 A是一个1 ~ P-2之间的整数。这个数是一个只有Alice知道的密码数字,没有必要告诉Bob,也不能让Eve知道。

Alice计算出的密钥=Bob计算出的密钥

  在步骤1-7中,双方交换数字一共有4个,P、G、G A mod P 和 G B mod P。根据这4个数字计算出Alice和Bob的共享密钥是非常困难的。
 如果Eve能欧知道A和B的任意一个数,那么计算G A*B 就很容易了,然而仅仅根据上面的4个数字很难求出A和B的。
 根据G A mod P 计算出A的有效算法到现在还没有出现,这问题成为有限域(finite field) 的 离散对数问题

 Diffie-Hellman密钥交换是利用了“离散对数问题”的复杂度来实现密钥的安全交换的,如果将“离散对数问题”改为“椭圆曲线上离散对数问题”,这样的算法就称为 椭圆曲线Diffie-Hellman 密钥交换。
 椭圆曲线Diffie-Hellman密钥交换在总体流程上是不变的,只是所利用的数学问题不同而已。椭圆曲线Diffie-Hellman密钥交换能够用较短的密钥长度实现较高的安全性。

 基于口令密码(password based encryption,PBE)就是一种根据口令生成密钥并用该密钥进行加密的方法。其中加密和解密使用同一个密钥。
 PBE有很多种实现方法。例如RFC2898和RFC7292 等规范中所描述的PBE就通过Java的javax.crypto包等进行了实现。此外,在通过密码软件PGP保存密钥时,也会使用PBE。
PBE的意义可以按照下面的逻辑来理解。

想确保重要消息的机制性。
  ↓
将消息直接保存到磁盘上的话,可能被别人看到。
  ↓
用密钥(CEK)对消息进行加密吧。
  ↓
但是这次又需要确保密钥(CEK)的机密性了。
  ↓
将密钥(CEK)直接保存在磁盘上好像很危险。
  ↓
用另一个密钥(KEK)对密钥进行加密(CEK)吧。
  ↓
等等!这次又需要确保密钥(KEK)的机密性了。进入死循环了。
  ↓
既然如此,那就用口令来生成密钥(KEK)吧。
  ↓
但只用口令容易遭到字典攻击
  ↓
那么就用口令和盐共同生成密钥(KEK)吧。
  ↓
盐可以和加密后的密钥(CEK)一切保存在磁盘上,而密钥(KEK)可以直接丢弃。
  ↓
口令就记在自己的脑子里吧。

PBE加密包括下列3个步骤:

  盐是由伪随机数生成器生成的随机数,在生成密钥(KEK)时会和口令一起被输入单向散列函数。
 密钥(KEK)是根据秘密的口令生成的,加盐好像没有什么意义,那么盐到底起到什么作用呢?
盐是用来防御字典攻击的 。字典攻击是一种事先进行计算并准备好候选密钥列表的方法。
 我们假设在生成KEK的时候没有加盐。那么主动攻击者Mallory就可以根据字典数据事先生成大量的候选KEK。
 在这里,事先是很重要的一点。这意味着Mallory可以在窃取到加密会话的密钥之前,就准备好了大量的候选KEK。当Mallory窃取加密的会话密钥后,就需要尝试将它解密,这是准备好了大量事先生成的候选KEK,就能够大幅度缩短尝试的时间,这就是 字典攻击 (dictionary attack)。
 如果在生成KEK时加盐,则盐的长度越大,候选KEK的数量也会随之增大,事先生成的的候选KEK就会变得非常困难。只要Mallory还没有得到盐,就无法生成候选KEK。这是因为加盐之后,候选KEK的数量会变得非常巨大。

 具有充足长度的密钥是无法用人脑记忆的。口令也是一样,我们也无法记住具有充足比特数的口令。
 在PBE中,我们通过口令生成密钥(KEK),在用这个密钥来加密会话密钥(CEK)。由于通过口令生成的密钥(KEK)强度不如由伪随机数生成器生成的会话密钥(CEK),这就好像是将一个牢固的保险柜的钥匙放在了一个不怎么牢固的保险柜保管,因此在使用基于口令的密钥时,需要将盐和加密后的CEK通过物理方法进行保护。例如将盐和加密后的CEK保存到存储卡随身携带。

 在生成KEK时,通过多次使用单向散列函数就可以提高安全性。例如,将盐和口令输入单向散列函数,进行1000次的散列函数所得到的散列值作为KEK来使用,是一个不错的方法。
 像这样将单向散列函数进行多次迭代的方法称为 拉伸 (stretching)。

该系列的主要内容来自《图解密码技术第三版》
我只是知识的搬运工
文章中的插图来源于原着

⑤ 04.现代常见分组加密算法

1.Triple DES

2.IDEA

3.RC6

4.RC6

5.ASE

其实就是有3个密钥k1,k2,k3,如果m表示明文,C表示密文,他们是这样操作的:

DES1(m)=>C1

DES2(C1)=>C2

DES3(C3)=>C3

DES密钥太短是其短板,3DES密钥长度为k1+k2+k3 = 56*3 = 168bit

既然都Triple自然就有double,为什么不用Double DES呢?

我们先来看下double des:

首先根据DESC密钥太短的特点,的确是有了double desc,可用中间相遇攻击破解(老师坑爹没讲什么是中间相遇攻击,日后补上),经过加密有2^64个可能的密文,密钥长度为112bit(56+56),所以选择密钥的可能性达到2^112,于是对给定一个明文P加密成密文有2^112/2^64 = 2^48种可能,对于给定两个明文密文对,虚警率降为2^(46-64)=2^-16,用中间相遇攻击大概可用2^57 可暴力破解

那么如何解决中间相遇攻击呢?于是设计出了Triple des,它一共有四种模式:

1.DES-EEE3:3个不同的密钥,顺序用三次加密算法

2.DES-EDE3:3个不同的密钥, 加密-解密-加密

3.DES-EEE2:两个不同的密钥,k1,k2,k1,依次k1加密,k2加密,k1加密

4.DES-EDE2:两个不同的密钥,k1,k2,k1,依次k1加密,k2解密,k1加密

这里我们着重介绍第四种,DES-EDE2

同DES相比有如下特点:

1.3DES安全性高,密钥长度大于DES

2.3DES可抵抗中间相遇攻击

3.可向下兼容,我们设k2=k1,则密钥均为k1,上图中A过程加密后在B过程解密,最后在C过程又加密,相当于仅用k1加密一次,兼容了DES,解密同理

4.相比于DES效率低些

要求:1.效率比3DES高

            2.至少和3DES一样安全,数据分组长度128bit

它有如下特点:

1.不属于Feistel结构,属于SP网络

2.加密,解密相似但不对称

3.支持128/32=Nb数据块大小

4.支持128/192/256(/32=Nk)密钥长度

5.结构简单速度快

什么是Feistel结构?

    Feistel 的优点在于:由于它是对称的密码结构,所以对信息的加密和解密的过程就极为相似,甚至完全一样。这就使得在实施的过程中,对编码量和线路传输的要求就减少了几乎一半

什么是SP网络结构?

    在这种密码的每一轮中,轮输入首先被一个由子密钥控制的可逆函数S作用,然后再对所得结果用置换(或可逆线性变换)P作用,S和P分别被称为混乱层和扩散层,主要起混乱和扩散作用

通过置换和替换迭代加密(最后一轮没有列混淆)

⑥ 下面哪种算法不需要密钥1.Aes2.Rsa3,Rca4,Md5

是md5,它是一种签名算法,MD5码以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

阅读全文

与下列不属于ec算法密钥长度的是相关的资料

热点内容
app登不了是怎么回事 浏览:252
dd命令u盘 浏览:568
单片机生日快乐程序 浏览:891
安卓手机连车载的叫什么 浏览:223
怎么让自己的手机键盘变得好看app 浏览:53
能看qq的文件夹 浏览:515
android二维码生成代码 浏览:567
焦炉气压缩机 浏览:402
imap接收邮件服务器地址 浏览:291
小乔肖恩解压密码 浏览:645
php网页网盘源码 浏览:181
签到任务源码 浏览:814
母亲节的文案怎么写app 浏览:984
加密协议aes找不到 浏览:250
java服务器端开发源码 浏览:551
编译器编译运行快捷键 浏览:333
住房app怎么快速选房 浏览:174
怎么在电脑上编译成功 浏览:214
单片机可调时钟设计方案 浏览:193
qq文件夹密码忘记怎么找回 浏览:683