常用加解密及摘要算法介绍及使用场景–MD5,SHA1,AES,DES,3DES,RSA,ECC

 加解密  常用加解密及摘要算法介绍及使用场景–MD5,SHA1,AES,DES,3DES,RSA,ECC已关闭评论
10月 292020
 

网上看到的一篇常用加解密算法、摘要算法的介绍文章,转载来自CSDN

数字签名信息加密是前后端开发经常使用的技术。应用场景包括:用户登录,交易,信息通讯等。

1、数字签名

数字签名 简单来说就是通过提供可鉴别 的数字信息 验证自身身份的一种方式。

一套 数字签名 通常定义两种 互补的运算,一个用于签名,另一个用于验证,分别  发送者持有能够代表自己的私钥,由接受者持有的与私钥对应的公钥,能够在接受到来自发送者信息时候用于验证其身份。

2、加密和解密

2.1 加密: 数据加密 基本过程,就是对来的铭文的文件或者数据 按照 某种算法 进行处理,使其成为不可读的一段代码,通常成为 “密文”。通过这样的途径,来达到保护数据 不被别人 非法窃取,阅读的目的。

2.2 解密:加密的逆过程为解密,将 编码的信息 转为为 原有的数据 的过程。

3、对称加密和非对称加密

面试相关问题:举例说一下有哪些常用的对称算法?及其使用场景。
常见的对称加密算法:DES3DESAES

常见的非对称加密算法:RSADSA

散列算法:SHA-1MD5等,其应用场景?

3.1、对称加密(共享密钥加密算法)

在对称加密算法中,使用的密钥只有一个,发送者  接受者 双方都是用这一个密钥进行 加密  解密。这就要求通信双方都必须事先知道这个密钥。

  • 数据加密过程:在对称加密算法中,数据发送方  明文 和加密密钥 一起经过特殊加密处理,生成 密文 进行发送。
  • 数据解密过程:数据接收方,收到密文后,若想读取原数据,则需要使用加密使用的密钥 即相同算法的 逆算法 对密文进行解密,才可以恢复到 可读的明文。

3.2、非对称加密算法(公开密钥加密算法)

在非对称加密算法中,她需要两个密钥,一个称为公开密钥,另一个为私有密钥。因为加密和解密使用的密钥不同,所以称为非对称加密算法。

  • 如果使用公钥对数据进行加密,只有用对应的私钥才可以对其进行解密。
  • 如果使用私钥对数据进行加密,只有用对应的公钥才可以对其进行解密。

4、常用的签名加密算法

4.1MD5算法 (相比于SHA1 安全性低,但是 速度快)

MD5算法用的是哈希函数,他的典型应用是对于一段信息产生信息摘要,以防止被篡改。严格来说MD5不算一种加密算法,而是一种 摘要算法。无论多长的输入,MD5都会输出长度为128bits的一个串(通常用16进制表示32个字符)。


public class MD5 {

    public static final byte[] computeMD5(byte[] content) {

        try {

            MessageDigest md5 = MessageDigest.getInstance(“MD5”);

            return md5.digest(content);

        } catch (NoSuchAlgorithmException e) {

            throw new RuntimeException(e);

        }

    }



    public static void main(String[] args) {

        String s1 = “hello world”;

        byte[] bytes = s1.getBytes();

        System.out.println(s1 +加密后的密文为:+computeMD5(bytes));

    }

}


// 输出结果:hello world经过MD5加密后的密文为:[[email protected]

 

4.2 SHA1算法 (相比于MD5 安全性高,但是 速度慢)

SHA1算法和MD5算法是一样流行 消息摘要算法,然而SHA1的安全性会高于MD5。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。


public class SHA1 {
    public static byte[] computeSHA1(byte[] content) {

        try {

            MessageDigest sha1 = MessageDigest.getInstance(“SHA1”);

            return sha1.digest(content);

        } catch (NoSuchAlgorithmException e) {

            throw new RuntimeException(e);

        }

    }



    public static void main(String[] args) {

        String s1 = “hello world”;

        byte[] bytes = s1.getBytes();

        System.out.println(s1 +加密后的密文为:+computeSHA1(bytes));

    }

}


// 输出结果:hello world经过SHA1加密后的密文为:[[email protected]

 

根据MD5SHA1的信息摘要及不可逆的特性,应用场景有 

  • 密码验证:服务器端存储用户密码加密后的内容,每次密码校验比较的是密文是否相同,确保服务器管理员也无法获取到用户使用的密码。
  • 文件的完整性比较:当下载一个文件时,服务器返回的信息中包括这个文件的MD5(或者SHA1),在本地下载完毕将其进行MD5加密,之后比较两个MD5只进行比较,如果一直则说明文件完整不存在丢包现象。
  • 文件上传:在上传文件信息的时候,将该文件的MD5同时上传给服务器。服务器中存储了这个文件MD5,并存储这个MD5只对应的已上传的字节长度,比如未上传为0,已完成为-1,已上传200自己,则值为200。可以用于匹配该文件在服务器中的状态,方便断点再传。只要源文件没有改,就算文件改了名字,换个账户都可以在服务器中找到对应的文件,避免存储多份相同文件,并可以提高二次上传时的速度。
  • 版权验证:当一个视频或者音创作出来的时候他的MD5是唯一的,翻录过后的版本的MD5会不同,可以用于版权验证。

4.3 HMAC算法

是一个密钥相关的 哈希运算消息认证码,HMAC运算利用 哈希算法(MD5SHA1等),以一个密钥  一个消息作为输入,生成一个消息摘要 作为输出。HMAC 发送方和接收方都有这个key进行计算,而没有这个key的第三方,则无法计算出正确的散列值,这样就可以防止数据被篡改。 该算法在多线程环境下是不安全的。

对称算法和非对称算法:

4.4 对称算法——AES/DES/3DES算法

AES/DES/3DES 都是对称的块加密算法,加解密过程是可逆的,

4.4.1 AES算法

AES加密算法是密码学中的高级加密标准,该加密算法采用的是 对称分组密码体制,密钥长度最少支持 128位,192位,256位,因而有AES128AES192AES256等常用的加密方式。分组长度为128位,算法更易于各种硬件和软件的实现。

AES本身就是为了取代DES的,AES具有更好的安全性,效率和灵活性。

4.4.2 DES算法

DES加密算法是一种 分组密码,以64位位 分组对数据加密,他的密钥长度是56位,加密和解密用同一个算法。
DES加密算法对于密钥进行保密,而公开算法,包括加密和解密算法。这样只有掌握了和发送方 相同密钥的人才能来解读由DES进行加密的密文数据。

4.4.3 3DES算法

是基于DES的对称算法,对 一块数据  三个不同的密钥 进行三次加密,安全性更高。
 

4.5 非对称算法——RSAECC算法

4.5.1 RSA算法

RSA算法是目前最具影响力的公钥加密算法。RSA是第一个同事用于加密和数字签名的算法,它能够抵抗到目前为止已知的所有密码攻击

RSA算法基于一个十分简单的数论试试,将两个大素数相乘十分容易,但是想要对乘积进行因式分解确十分困难,因此可以将乘积公开作为加密密钥。

4.5.2 ECC算法

ECC算法的主要优势是,在某一些情况下,它可以生成比其他方法更小的密钥,比如RSA算法,并提供相当或者更高级别的安全等级。不过他的缺点是 加密和解密操作的实现会比其他机制时间要长,对于CPU的消耗严重。

utm   详细X
基本翻译
abbr. 统一威胁管理(Unified Threat Management);通用横墨卡托投影(Universal Transverse Mercator projection)
网络释义
UTM: 统一威胁管理
UTM UTM: 统一威胁管理
UTM-: 通用横向墨卡托图

RSA加密解密及数字签名的Java实现

 加解密  RSA加密解密及数字签名的Java实现已关闭评论
6月 132016
 

这篇文章也不错,收藏备用,来源:http://my.oschina.net/jiangli0502/blog/171263


  RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

    RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密算法

    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

    关于RSA算法的原理,这里就不再详加介绍,网上各种资源一大堆。下面就开始介绍RSA加密解密JAVA类的具体实现。

import java.security.MessageDigest; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class Coder { public static final String KEY_SHA="SHA"; public static final String KEY_MD5="MD5"; /**
     * BASE64解密
     * @param key
     * @return  * @throws Exception
     */ public static byte[] decryptBASE64(String key) throws Exception{ return (new BASE64Decoder()).decodeBuffer(key);
    } /**
     * BASE64加密
     * @param key
     * @return  * @throws Exception
     */ public static String encryptBASE64(byte[] key)throws Exception{ return (new BASE64Encoder()).encodeBuffer(key);
    } /**
     * MD5加密
     * @param data
     * @return  * @throws Exception
     */ public static byte[] encryptMD5(byte[] data)throws Exception{
        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
        md5.update(data); return md5.digest();
    } /**
     * SHA加密
     * @param data
     * @return  * @throws Exception
     */ public static byte[] encryptSHA(byte[] data)throws Exception{
        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
        sha.update(data); return sha.digest();
    }
}

     先提供Coder编码类,该类封装了基本的Base64、md5和SHA加密解密算法。Java对这些算法的实现提供了很好的API封装,开发人员只需调用这些API就可很简单方便的实现数据的加密与解密。

    下面提供RSA加密解密类,该类为Coder类子类,因为其中对RSA公私密钥的保存进行了一层Base64加密处理。

    RSA加密解密类静态常量

       public static final String KEY_ALGORTHM="RSA";// public static final String SIGNATURE_ALGORITHM="MD5withRSA"; public static final String PUBLIC_KEY = "RSAPublicKey";//公钥 public static final String PRIVATE_KEY = "RSAPrivateKey";//私钥

    RSA加密解密的实现,需要有一对公私密钥,公私密钥的初始化如下:

/**
     * 初始化密钥
     * @return
     * @throws Exception
     */ public static Map<String,Object> initKey()throws Exception{
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORTHM);
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair(); //公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); //私钥 RSAPrivateKey privateKey =  (RSAPrivateKey) keyPair.getPrivate();
        
        Map<String,Object> keyMap = new HashMap<StringObject>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey); return keyMap;
    }

      从代码中可以看出密钥的初始化长度为1024位,密钥的长度越长,安全性就越好,但是加密解密所用的时间就会越多。而一次能加密的密文长度也与密钥的长度成正比。一次能加密的密文长度为:密钥的长度/8-11。所以1024bit长度的密钥一次可以加密的密文为1024/8-11=117bit。所以非对称加密一般都用于加密对称加密算法的密钥,而不是直接加密内容。对于小文件可以使用RSA加密,但加密过程仍可能会使用分段加密。

    从map中获取公钥、私钥

/**  * 取得公钥,并转化为String类型
     * @param keyMap  * @return  * @throws Exception  */
    public static String getPublicKey(Map<String, Object> keyMap)throws Exception{
        Key key = (Key) keyMap.get(PUBLIC_KEY);  
        return encryptBASE64(key.getEncoded());     
    }

    /**  * 取得私钥,并转化为String类型
     * @param keyMap  * @return  * @throws Exception  */
    public static String getPrivateKey(Map<String, Object> keyMap) throws Exception{
        Key key = (Key) keyMap.get(PRIVATE_KEY);  
        return encryptBASE64(key.getEncoded());     
    }

    对于RSA产生的公钥、私钥,我们可以有两种方式可以对信息进行加密解密。私钥加密-公钥解密 和 公钥加密-私钥解密。
 

    私钥加密

/**
     * 用私钥加密
     * @param data	加密数据
     * @param key	密钥
     * @return  * @throws Exception
     */ public static byte[] encryptByPrivateKey(byte[] data,String key)throws Exception{ //解密密钥 byte[] keyBytes = decryptBASE64(key); //取私钥 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); //对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data);
    }

    私钥解密

/**
     * 用私钥解密 * @param data 	加密数据  * @param key	密钥
     * @return
     * @throws Exception  */
    public static byte[] decryptByPrivateKey(byte[] data,String key)throws Exception{
        //对私钥解密 byte[] keyBytes = decryptBASE64(key); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM); Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODEprivateKey); return cipher.doFinal(data);
    }

    公钥加密

/**
     * 用公钥加密
     * @param data	加密数据
     * @param key	密钥
     * @return  * @throws Exception
     */ public static byte[] encryptByPublicKey(byte[] data,String key)throws Exception{ //对公钥解密 byte[] keyBytes = decryptBASE64(key); //取公钥 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
        Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data);
    }

    私钥加密

/**
     * 用公钥解密
     * @param data 加密数据  * @param key	密钥
     * @return
     * @throws Exception  */
    public static byte[] decryptByPublicKey(byte[] data,String key)throws Exception{
        //对私钥解密 byte[] keyBytes = decryptBASE64(key); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM); Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        
        //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODEpublicKey); return cipher.doFinal(data);
    }

    关于数字签名,先了解下何为数字签名。数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。数字签名是非对称密钥加密技术与数字摘要技术的应用。简单地说,所谓数字签名就是附加在数据单元上的一些数据,或是对数据单元所作的密码变换。这种数据或变换允许数据单元的接收者用以确认数据单元的来源和数据单元的完整性并保护数据,防止被人(例如接收者)进行伪造。

    数字签名的主要功能如下:
 

    保证信息传输的完整性、发送者的身份认证、防止交易中的抵赖发生。

    数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。

    数字签名是个加密的过程,数字签名验证是个解密的过程。

     数字签名算法依靠公钥加密技术来实现的。在公钥加密技术里,每一个使用者有一对密钥:一把公钥和一把私钥。公钥可以自由发布,但私钥则秘密保存;还有一个要求就是要让通过公钥推算出私钥的做法不可能实现。

    普通的数字签名算法包括三种算法:

    1.密码生成算法;

    2.标记算法;

   3.验证算法

    通过RSA加密解密算法,我们可以实现数字签名的功能。我们可以用私钥对信息生成数字签名,再用公钥来校验数字签名,当然也可以反过来公钥签名,私钥校验。

    私钥签名
 

/**
     *	用私钥对信息生成数字签名
     * @param data	//加密数据
     * @param privateKey	//私钥
     * @return  * @throws Exception
     */ public static String sign(byte[] data,String privateKey)throws Exception{ //解密私钥 byte[] keyBytes = decryptBASE64(privateKey); //构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); //指定加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM); //取私钥匙对象 PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec); //用私钥对信息生成数字签名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateKey2);
        signature.update(data); return encryptBASE64(signature.sign());
    }

    公钥校验 

/**
     * 校验数字签名
     * @param data	加密数据
     * @param publicKey	公钥
     * @param sign	数字签名
     * @return  * @throws Exception
     */ public static boolean verify(byte[] data,String publicKey,String sign)throws Exception{ //解密公钥 byte[] keyBytes = decryptBASE64(publicKey); //构造X509EncodedKeySpec对象 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); //指定加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM); //取公钥匙对象 PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);
        
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicKey2);
        signature.update(data); //验证签名是否正常 return signature.verify(decryptBASE64(sign));
        
    }

rsa,公钥,私钥,签名,验签,加密,解密 关系理解

 加解密  rsa,公钥,私钥,签名,验签,加密,解密 关系理解已关闭评论
6月 132016
 

链接:http://www.zhihu.com/question/25912483/answer/31653639

来源:知乎

有人提问:RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密?

我们来回顾一下RSA的加密算法。我们从公钥加密算法和签名算法的定义出发,用比较规范的语言来描述这一算法。

RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法)。

  • (PK, SK)\leftarrow KeyGen(\lambda)。密钥生成算法以安全常数\lambda作为输入,输出一个公钥PK,和一个私钥SK。安全常数用于确定这个加密算法的安全性有多高,一般以加密算法使用的质数p的大小有关。\lambda越大,质数p一般越大,保证体制有更高的安全性。在RSA中,密钥生成算法如下:算法首先随机产生两个不同大质数p和q,计算N=pq。随后,算法计算欧拉函数\varphi(N)=(p-1)(q-1)。接下来,算法随机选择一个小于\varphi(N)的整数e,并计算e关于\varphi(N)的模反元素d。最后,公钥为PK=(N, e),私钥为SK=(N, d)。
  • CT \leftarrow Encrypt(PK,M)。加密算法以公钥PK和待加密的消息M作为输入,输出密文CT。在RSA中,加密算法如下:算法直接输出密文为CT=M^e \bmod N
  • M \leftarrow Decrypt(SK,CT)。解密算法以私钥SK和密文CT作为输入,输出消息M。在RSA中,解密算法如下:算法直接输出明文为M=CT^d \bmod N。由于e和d在\varphi(N)下互逆,因此我们有:CT^d=M^{ed}=M \bmod N

所以,从算法描述中我们也可以看出:公钥用于对数据进行加密,私钥用于对数据进行解密。当然了,这个也可以很直观的理解:公钥就是公开的密钥,其公开了大家才能用它来加密数据。私钥是私有的密钥,谁有这个密钥才能够解密密文。否则大家都能看到私钥,就都能解密,那不就乱套了。

我们再来回顾一下RSA签名体制。签名体制同样包含3个算法:KeyGen(密钥生成算法),Sign(签名算法),Verify(验证算法)。

  • (PK,SK) \leftarrow KeyGen(\lambda)。密钥生成算法同样以安全常数\lambda作为输入,输出一个公钥PK和一个私钥SK。在RSA签名中,密钥生成算法与加密算法完全相同。
  • \sigma \leftarrow Sign(SK,M)。签名算法以私钥SK和待签名的消息M作为输入,输出签名\sigma。在RSA签名中,签名算法直接输出签名为\sigma = M^d \bmod N。注意,签名算法和RSA加密体制中的解密算法非常像
  • b \leftarrow Verify(PK,\sigma,M)。验证算法以公钥PK,签名\sigma以及消息M作为输入,输出一个比特值b。b=1意味着验证通过。b=0意味着验证不通过。在RSA签名中,验证算法首先计算M'=\sigma^e \bmod N,随后对比M’与M,如果相等,则输出b=1,否则输出b=0。注意:验证算法和RSA加密体制中的加密算法非常像

所以,在签名算法中,私钥用于对数据进行签名,公钥用于对签名进行验证。这也可以直观地进行理解:对一个文件签名,当然要用私钥,因为我们希望只有自己才能完成签字。验证过程当然希望所有人都能够执行,大家看到签名都能通过验证证明确实是我自己签的。

那么,为什么题主问这么一个问题呢?我们可以看到,RSA的加密/验证,解密/签字过程太像了。同时,RSA体制本身就是对称的:如果我们反过来把e看成私钥,d看成公钥,这个体制也能很好的执行。我想正是由于这个原因,题主在学习RSA体制的时候才会出现这种混乱。那么解决方法是什么呢?建议题主可以学习一下其他的公钥加密体制以及签名体制。其他的体制是没有这种对称性质的。举例来说,公钥加密体制的话可以看一看ElGamal加密,以及更安全的Cramer-Shoup加密。签名体制的话可以进一步看看ElGamal签名,甚至是BLS签名,这些体制可能能够帮助题主更好的弄清加密和签名之间的区别和潜在的联系。

至于题主问的加密和签名是怎么结合的。这种体制叫做签密方案(SignCrypt),RSA中,这种签密方案看起来特别特别像,很容易引起混乱。在此我不太想详细介绍RSA中的加密与签字结合的方案。我想提醒题主的是,加密与签字结合时,两套公私钥是不同的。

Java扩展算法和辅助工具

 java, 加解密  Java扩展算法和辅助工具已关闭评论
12月 212015
 

Java扩展算法和辅助工具,记录下,转自:http://blog.csdn.net/danwell7/article/details/8426853

获取权限文件

Sun在其下载页面(http://www.oracle.com/technetwork/java/javase/downloads/index.html)提供了权限文件的下载地址,对应Java 7 和 Java 6

1356360474_5116

打开压缩包local_policy.jar和US_export_policy.jar是此次配置中用到的文件

配置权限文件

需要在JDKJRE环境中,或者是JRE环境配置上述两个jar文件。

     切换到%JDK_Home%\jre\lib\security目录下覆盖原有的文件。同时,可能有必要在%JRE_Home%\lib\security下对应覆盖这两个文件

配置权限文件的最终目的是为了使应用在运行环境中或德相应的权限,可以加强应用的安全性

扩充算法支持

Bouncy Castle目前提供的加密组件组件包的版本是1.47,自1.40版本开始,Bouncy Castle

提供了对IDEA(International Data Encryption Algorithm,国际数据加密算法)。下载最新的加密组件包,主要是bcprov-jdk15on-147.jarbcprov-ext-jdk15on-147.jar两个文件如下图

1356360574_8952

http://www.bouncycastle.org/latest_releases.html

配置方式

%JDK_Home%\jre\lib\security\java.security文件下配置根据:

security.provider.<n>=<className>,则加入Bouncy Castle加密组件的

安全提供者做法:

方式一:

#增进BouncyCastleProvider

security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider

最后,需要将bcprov-ext-dk15on-147.jar导入到%JRE_Home%\lib\ext即可

方式二:

通过明显的代码调用方式引入支持者,这儿使用Security类的addProvider()方法,此方法

需要在初始化密钥工厂.密钥生成器等引擎类之前,调用如下代码:

Security.addProvider(new BouncyCastleProvider())

检测安装

Java 7不支持MD4IDEA算法,做了上述配置后,使用MD4算法可以参考

public static byte[] encodeMD4(byte [] data) throws Exception{

MessageDigest md = MessageDigest.getInstance(“MD4”);

md.update(data);

return md.digest();

}

辅助工具Commons Codec

Apache旗下的一款开源软件,主要用于编码格式的转换,如Base64.二进制.十六进制.字符集和Url编码的转换。甚至Commons Codec还提供了语言编码的转换。除此之外,Commons Codec还对Java的原生消息摘要做了良好的封装,提高了方法的易用性

http://commons.apache.org/codec/download_codec.cgi

下载commons-codec-1.7-bin.zip即可

Java 环境下使用 AES 密钥长度限制等特殊情况处理及 PKCS5 和 PKCS7 填充说明( Illegal key size or default parameters问题解决)

 java, 加解密  Java 环境下使用 AES 密钥长度限制等特殊情况处理及 PKCS5 和 PKCS7 填充说明( Illegal key size or default parameters问题解决)已关闭评论
12月 182015
 

补充下AES 加密问题及PKCS5 和 PKCS7 填充说明

近些年DES使用越来越少,原因就在于其使用56位密钥,比较容易被破解,近些年来逐渐被AES替代,AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据.

 在 Java 环境下使用 AES 加密,在密钥长度和字节填充方面有一些比较特殊的处理。

1. 密钥长度问题

    默认 Java 中仅支持 128 位密钥,当使用 256 位密钥的时候,会报告密钥长度错误(或者 Illegal key size or default parameters)

Invalid AES key length

   你需要下载一个支持更长密钥的包。这个包叫做 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6,可以从这里下载,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

   下载之后,解压后,可以看到其中包含两个包:

    local_policy.jar

    US_export_policy.jar

    看一下你的 JRE 环境,将 JRE 环境中 lib\lib\security 中的同名包替换掉。

2. Base64 问题

     Apache 提供了 Base64 的实现,可以从这里下载。

    下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi

     编码

// 编码 String asB64 = new Base64().encodeToString("some string".getBytes("utf-8"));
System.out.println(asB64); // 输出为: c29tZSBzdHJpbmc=

     解码   

// 解码 byte[] asBytes = new Base64().getDecoder().decode("c29tZSBzdHJpbmc=");
System.out.println(new String(asBytes, "utf-8")); // 输出为: some string

 

     如果你已经使用 Java 8,那么就不需要再选用第三方的实现了,在 java.util 包中已经包含了 Base64 的处理。

     编码的方式

// 编码 String asB64 = Base64.getEncoder().encodeToString("some string".getBytes("utf-8"));
System.out.println(asB64); // 输出为: c29tZSBzdHJpbmc=

     解码处理

// 解码 byte[] asBytes = Base64.getDecoder().decode("c29tZSBzdHJpbmc=");
System.out.println(new String(asBytes, "utf-8")); // 输出为: some string

 

3. 关于 PKCS5 和 PKCS7 填充问题

PKCS #7 填充字符串由一个字节序列组成,每个字节填充该填充字节序列的长度。

假定块长度为 8,数据长度为 9,
          数据: FF FF FF FF FF FF FF FF FF
PKCS7 填充: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07

简单地说, PKCS5, PKCS7和SSL3, 以及CMS(Cryptographic Message Syntax)

有如下相同的特点:
1)填充的字节都是一个相同的字节
2)该字节的值,就是要填充的字节的个数

如果要填充8个字节,那么填充的字节的值就是0×8;
要填充7个字节,那么填入的值就是0×7;

如果只填充1个字节,那么填入的值就是0×1;

这种填充方法也叫PKCS5, 恰好8个字节时还要补8个字节的0×08

正是这种即使恰好是8个字节也需要再补充字节的规定,可以让解密的数据很确定无误的移除多余的字节。

pkcs7_padding

 

在PKCS# Padding中说:

  1. 因为恢复的明文的最后一个字节 告诉你 存在多少个填充字节, 用PKCS#5 填充 的加密方法, 即使在输入的明文长度 恰好是 块大小(Block Size)整数倍 , 也会增加一个完整的填充块. 否则,恢复出来的明文的最后一个字节可能是实际的消息字节.
  2. 因为第1个因素限制了 使用PKCS#填充的 对称加密算法的 输入块大小(Block Size, 注意不是输入的明文的总长度 total input length), 最大只能是256个字节.   因为大多数对称块加密算法 通常使用8字节或者16字节的块, 所以,这不是一个问题
  3. 使用ECB模式填充可能会有安全问题.
  4. 使用PKCS#5填充 可以很方便地检测明文中的错误.

标准

PKCS #7: Cryptographic Message Syntax

在 10.3节中讲到了上面提到的填充算法,  对Block Size并没有做规定

PKCS #5: Password-Based Cryptography Specification

在6.1.1 中对 填充做了说明
但是因为该标准 只讨论了 8字节(64位) 块的加密, 对其他块大小没有做说明
其 填充算法跟 PKCS7是一样的

后来 AES 等算法, 把BlockSize扩充到 16个字节

比如, Java中
Cipher.getInstance(“AES/CBC/PKCS5Padding”)
这个加密模式
跟C#中的
RijndaelManaged cipher = new RijndaelManaged();
cipher.KeySize = 128;
cipher.BlockSize = 128;
cipher.Mode = CipherMode.CBC;
cipher.Padding = PaddingMode.PKCS7;
的加密模式是一样的

因为AES并没有64位的块, 如果采用PKCS5, 那么实质上就是采用PKCS7

对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)

 加解密  对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)已关闭评论
12月 182015
 

对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB),这篇文章讲的比较清楚,分享下:

. AES对称加密:


                                                      AES加密


                         分组


 

 

分组密码的填充


                                                   分组密码的填充

 

e.g.:

                                                         PKCS#5填充方式

 

 


 

流密码:


 

 

分组密码加密中的四种模式:

3.1 ECB模式

优点:

1.简单;

2.有利于并行计算;

3.误差不会被传送;

缺点:

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

2.可能对明文进行主动攻击;

 


3.2 CBC
模式:

优点:

1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,SSLIPSec的标准。

缺点:

1.不利于并行计算;

2.误差传递;

3.需要初始化向量IV

 

3.3 CFB模式:


 优点:

1.隐藏了明文模式;

2.分组密码转化为流模式;

3.可以及时加密传送小于分组的数据;

缺点:

1.不利于并行计算;

2.误差传送:一个明文单元损坏影响多个单元;

3.唯一的IV;

 

3.4 OFB模式:


 优点
:

1.隐藏了明文模式;

2.分组密码转化为流模式;

3.可以及时加密传送小于分组的数据;

缺点:

1.不利于并行计算;

2.对明文的主动攻击是可能的;

3.误差传送:一个明文单元损坏影响多个单元;

转自:http://www.cnblogs.com/happyhippy/archive/2006/12/23/601353.html

12月 082015
 

DES使用越来越少,原因就在于其使用56位密钥,比较容易被破解,近些年来逐渐被AES替代,AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据(目前默认java仅支持128位密钥,需下载扩展包支持256位,见java扩展算法与辅助工具)。本文就简单介绍如何通过JAVA实现AES加密。

网上很多java 实现AES的代码都有这样那样问题,现摘录《java加密与解密的艺术》中关于AES的代码, 简单明了,关键是有效!!!

JAVA实现

package test.rsa;

import java.security.Key;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class AESCoder {
public static final String KEY_ALGORITHM = “AES”;

public static final String CIPHER_ALGORITHM = “AES/ECB/PKCS5Padding”;

private static Key toKey(byte[] key) throws Exception {
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}

public static byte[] decrypt(byte[] data, byte[] key) throws Exception{
Key k = toKey(key);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, k);
return cipher.doFinal(data);
}

public static byte[] encrypt(byte[] data, byte[] key) throws Exception{
Key k = toKey(key);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, k);
return cipher.doFinal(data);
}

public static byte[] initKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
kg.init(128);
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();

}

public static void main(String[] args) throws Exception {
String inputStr=”测试 AES 密钥密钥密钥密钥”;
byte[] inputData = inputStr.getBytes();
System.out.println(“原文[arrays]:\t” + Arrays.toString(inputData));
System.out.println(“原文:\t” + inputStr);

byte[] key = initKey();
System.out.println(“密钥[arrays]:\t” + Arrays.toString(key));
System.out.println(“密钥[base64]:\t” + Base64.encodeBase64String(key));

inputData = encrypt(inputData, key);
System.out.println(“加密后[arrays]:\t” + Arrays.toString(inputData));
System.out.println(“加密后[base64]:\t” + Base64.encodeBase64String(inputData));

byte[] outputData= decrypt(inputData, key);
System.out.println(“解密后[arrays]:\t” + Arrays.toString(outputData));
System.out.println(“解密后[base64]:\t” + new String(outputData));

}

}

密钥的合成及base64转码方式,给我们保存及传输提供了想象空间。

9月 162015
 

网上找到到一个加解密内容的系列文章,强烈推荐:

 

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 “Rhinedoll”。)

 

AES是美国国家标准技术研究所NIST旨在取代DES的21世纪的加密标准。

AES的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。1998年NIST开始AES第一轮分析、测试和征集,共产生了15个候选算法。1999年3月完成了第二轮AES2的分析、测试。2000年10月2日美国政府正式宣布选中比利时密码学家Joan Daemen 和 Vincent Rijmen 提出的一种密码算法RIJNDAEL 作为 AES.   在应用方面,尽管DES在安全上是脆弱的,但由于快速DES芯片的大量生产,使得DES仍能暂时继续使用,为提高安全强度,通常使用独立密钥的三级DES。但是DES迟早要被AES代替。流密码体制较之分组密码在理论上成熟且安全,但未被列入下一代加密标准。
AES加密数据块和密钥长度可以是128比特、192比特、256比特中的任意一个。

AES加密有很多轮的重复和变换。大致步骤如下:

1、密钥扩展(KeyExpansion),

2、初始轮(Initial Round),

3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,

4、最终轮(Final Round),最终轮没有MixColumns。

 

JDK对DESede算法的支持

密钥长度:128位
工作模式:ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128
填充方式:Nopadding/PKCS5Padding/ISO10126Padding/
  

工作模式和填充方式请参考:      JAVA加密解密基础

十六进制工具类Hex.java,见:   java byte数组与十六进制字符串互转 
AES加密解密的java实现:
AESCoder.java

Java代码  收藏代码

  1. import java.security.Key;  
  2. import java.security.NoSuchAlgorithmException;  
  3.   
  4. import javax.crypto.Cipher;  
  5. import javax.crypto.KeyGenerator;  
  6. import javax.crypto.SecretKey;  
  7. import javax.crypto.spec.SecretKeySpec;  
  8.   
  9. /** 
  10.  * AES Coder<br/> 
  11.  * secret key length:   128bit, default:    128 bit<br/> 
  12.  * mode:    ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128<br/> 
  13.  * padding: Nopadding/PKCS5Padding/ISO10126Padding/ 
  14.  *  
  15.  */  
  16. public class AESCoder {  
  17.       
  18.     /** 
  19.      * 密钥算法 
  20.     */  
  21.     private static final String KEY_ALGORITHM = “AES”;  
  22.       
  23.     private static final String DEFAULT_CIPHER_ALGORITHM = “AES/ECB/PKCS5Padding”;  
  24.       
  25.     /** 
  26.      * 初始化密钥 
  27.      *  
  28.      * @return byte[] 密钥  
  29.      * @throws Exception 
  30.      */  
  31.     public static byte[] initSecretKey() {  
  32.         //返回生成指定算法的秘密密钥的 KeyGenerator 对象  
  33.         KeyGenerator kg = null;  
  34.         try {  
  35.             kg = KeyGenerator.getInstance(KEY_ALGORITHM);  
  36.         } catch (NoSuchAlgorithmException e) {  
  37.             e.printStackTrace();  
  38.             return new byte[0];  
  39.         }  
  40.         //初始化此密钥生成器,使其具有确定的密钥大小  
  41.         //AES 要求密钥长度为 128  
  42.         kg.init(128);  
  43.         //生成一个密钥  
  44.         SecretKey  secretKey = kg.generateKey();  
  45.         return secretKey.getEncoded();  
  46.     }  
  47.       
  48.     /** 
  49.      * 转换密钥 
  50.      *  
  51.      * @param key   二进制密钥 
  52.      * @return 密钥 
  53.      */  
  54.     private static Key toKey(byte[] key){  
  55.         //生成密钥  
  56.         return new SecretKeySpec(key, KEY_ALGORITHM);  
  57.     }  
  58.       
  59.     /** 
  60.      * 加密 
  61.      *  
  62.      * @param data  待加密数据 
  63.      * @param key   密钥 
  64.      * @return byte[]   加密数据 
  65.      * @throws Exception 
  66.      */  
  67.     public static byte[] encrypt(byte[] data,Key key) throws Exception{  
  68.         return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);  
  69.     }  
  70.       
  71.     /** 
  72.      * 加密 
  73.      *  
  74.      * @param data  待加密数据 
  75.      * @param key   二进制密钥 
  76.      * @return byte[]   加密数据 
  77.      * @throws Exception 
  78.      */  
  79.     public static byte[] encrypt(byte[] data,byte[] key) throws Exception{  
  80.         return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);  
  81.     }  
  82.       
  83.       
  84.     /** 
  85.      * 加密 
  86.      *  
  87.      * @param data  待加密数据 
  88.      * @param key   二进制密钥 
  89.      * @param cipherAlgorithm   加密算法/工作模式/填充方式 
  90.      * @return byte[]   加密数据 
  91.      * @throws Exception 
  92.      */  
  93.     public static byte[] encrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{  
  94.         //还原密钥  
  95.         Key k = toKey(key);  
  96.         return encrypt(data, k, cipherAlgorithm);  
  97.     }  
  98.       
  99.     /** 
  100.      * 加密 
  101.      *  
  102.      * @param data  待加密数据 
  103.      * @param key   密钥 
  104.      * @param cipherAlgorithm   加密算法/工作模式/填充方式 
  105.      * @return byte[]   加密数据 
  106.      * @throws Exception 
  107.      */  
  108.     public static byte[] encrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{  
  109.         //实例化  
  110.         Cipher cipher = Cipher.getInstance(cipherAlgorithm);  
  111.         //使用密钥初始化,设置为加密模式  
  112.         cipher.init(Cipher.ENCRYPT_MODE, key);  
  113.         //执行操作  
  114.         return cipher.doFinal(data);  
  115.     }  
  116.       
  117.       
  118.       
  119.     /** 
  120.      * 解密 
  121.      *  
  122.      * @param data  待解密数据 
  123.      * @param key   二进制密钥 
  124.      * @return byte[]   解密数据 
  125.      * @throws Exception 
  126.      */  
  127.     public static byte[] decrypt(byte[] data,byte[] key) throws Exception{  
  128.         return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);  
  129.     }  
  130.       
  131.     /** 
  132.      * 解密 
  133.      *  
  134.      * @param data  待解密数据 
  135.      * @param key   密钥 
  136.      * @return byte[]   解密数据 
  137.      * @throws Exception 
  138.      */  
  139.     public static byte[] decrypt(byte[] data,Key key) throws Exception{  
  140.         return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);  
  141.     }  
  142.       
  143.     /** 
  144.      * 解密 
  145.      *  
  146.      * @param data  待解密数据 
  147.      * @param key   二进制密钥 
  148.      * @param cipherAlgorithm   加密算法/工作模式/填充方式 
  149.      * @return byte[]   解密数据 
  150.      * @throws Exception 
  151.      */  
  152.     public static byte[] decrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{  
  153.         //还原密钥  
  154.         Key k = toKey(key);  
  155.         return decrypt(data, k, cipherAlgorithm);  
  156.     }  
  157.   
  158.     /** 
  159.      * 解密 
  160.      *  
  161.      * @param data  待解密数据 
  162.      * @param key   密钥 
  163.      * @param cipherAlgorithm   加密算法/工作模式/填充方式 
  164.      * @return byte[]   解密数据 
  165.      * @throws Exception 
  166.      */  
  167.     public static byte[] decrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{  
  168.         //实例化  
  169.         Cipher cipher = Cipher.getInstance(cipherAlgorithm);  
  170.         //使用密钥初始化,设置为解密模式  
  171.         cipher.init(Cipher.DECRYPT_MODE, key);  
  172.         //执行操作  
  173.         return cipher.doFinal(data);  
  174.     }  
  175.       
  176.     private static String  showByteArray(byte[] data){  
  177.         if(null == data){  
  178.             return null;  
  179.         }  
  180.         StringBuilder sb = new StringBuilder(“{“);  
  181.         for(byte b:data){  
  182.             sb.append(b).append(“,”);  
  183.         }  
  184.         sb.deleteCharAt(sb.length()-1);  
  185.         sb.append(“}”);  
  186.         return sb.toString();  
  187.     }  
  188.       
  189.     public static void main(String[] args) throws Exception {  
  190.         byte[] key = initSecretKey();  
  191.         System.out.println(“key:”+showByteArray(key));  
  192.           
  193.         Key k = toKey(key);  
  194.           
  195.         String data =“AES数据”;  
  196.         System.out.println(“加密前数据: string:”+data);  
  197.         System.out.println(“加密前数据: byte[]:”+showByteArray(data.getBytes()));  
  198.         System.out.println();  
  199.         byte[] encryptData = encrypt(data.getBytes(), k);  
  200.         System.out.println(“加密后数据: byte[]:”+showByteArray(encryptData));  
  201.         System.out.println(“加密后数据: hexStr:”+Hex.encodeHexStr(encryptData));  
  202.         System.out.println();  
  203.         byte[] decryptData = decrypt(encryptData, k);  
  204.         System.out.println(“解密后数据: byte[]:”+showByteArray(decryptData));  
  205.         System.out.println(“解密后数据: string:”+new String(decryptData));  
  206.           
  207.     }  
  208. }  

转自:http://aub.iteye.com/blog/1133494

 Posted by at 上午8:52
9月 162015
 

网上的加密解密系列文章

Java  加密解密基础

密码学是研究编制密码和破译密码的技术科学。研究密码变化的客观规律,应用于编制密码以保守通信秘密的,称为编码学;应用于破译密码以获取通信情报的,称为破译学,总称密码学。

 

密码学常用术语

 

明文: 待加密数据。

密文: 明文经过加密后数据。

加密: 将明文转换为密文的过程。

加密算法: 将明文转换为密文的转换算法。

加密密钥: 通过加密算法进行加密操作的密钥。

解密: 将密文转换为铭文的过程。

解密算法: 将密文转换为明文的转换算法。

解密密钥: 通过解密短发进行解密操作的密钥。

 

密码学分类

1. 按时间分

a. 古典密码:以字符为基本加密单元。

b. 现代密码:以信息块为基本加密单元。

 

2 按保密内容的算法划分

a. 受限制算法:算法的保密性基于保持算法的秘密。

b. 基于密钥算法:算法的保密性基于对密钥的保密。

 

3. 按密钥体制划分

a. 对称密码体制:也叫单钥或私钥密码体制,加密过程与解密过程使用同一套密钥。对应的算法就是对称加密算法,例如 DES , AES 

b. 非对称密码体制:也叫双钥或公钥密码体制,加密过程与解密过程使用不同的密钥。对应的算法就是非对称加密算法,例如 RSA 

 

4. 按明文处理方式划分

a. 流密码:也称为序列密码,加密时每次加密一位或者一个字节的明文。例如 RC4 算法。

b. 分组密码:加密时将明文分成固定长度的组,用同一个密钥和算法对每一组进行加密输出也是固定长度的明文。当最后一组大小不满足指定的分组大小时,

有两种处理模式:

 

无填充模式,直接对剩余数据进行加密,此组加密后大小与剩余数据有关;

有填充模式,对于不满足指定长度分组的进行数据填充;如果恰巧最后一组数据与指定分组大小相同,那么直接添加一个指定大小的分组;填充的最后一个字节记录了填充的字节数。

 

 

 

分组密码工作模式简介  

.电子密码本模–ECB

将明文的各个分组独立的使用相同的密钥进行加密,这种方式加密时各分组的加密独立进行互不干涉,因而可并行进行。同样因为各分组独立加密的缘故,相同的明文分组加密之后具有相同的密文。该模式容易暴露明文分组的统计规律和结构特征。不能防范替换攻击。 
其实照实现来看, ECB 的过程只是把明文进行分组,然后分别加密,最后串在一起的过程。当消息长度超过一个分组时,不建议使用该模式。在每个分组中增加随机位 ( 如 128 位分组中 96 位为有效明文, 32 位的随机数 ) 则可稍微提高其安全性 , 但这样无疑造成了加密过程中数据的扩张。

优点 :

1.简单;

2.有利于并行计算;

3.误差不会被传送;

缺点 :

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

2.可能对明文进行主动攻击;

 

2.密码分组链接模 — CBC

需要一个初始化向量 IV ,第一组明文与初始化向量进行异或运算后再加密,以后的每组明文都与前一组的密文进行异或运算后再加密。 IV 不需要保密,它可以明文形式与密文一起传送。

优点:

1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。

缺点:

1.不利于并行计算;

2.误差传递;

3.需要初始化向量IV

   

3. 密文反馈模式–CFB  

需要一个初始化向量IV ,加密后与第一个分组明文进行异或运算产生第一组密文,然后对第一组密文加密后再与第二组明文进行异或运算缠身第二组密文,一次类推,直到加密完毕。

优点:

1.隐藏了明文模式;

2.分组密码转化为流模式;

3.可以及时加密传送小于分组的数据;

缺点 :

1.不利于并行计算;

2.误差传送:一个明文单元损坏影响多个单元;

3.唯一的IV;

 

4. 输出反馈模式–OFB

需要一个初始化向量IV ,加密后得到第一次加密数据,此加密数据与第一个分组明文进行异或运算产生第一组密文,然后对第一次加密数据进行第二次加密,得到第二次加密数据,第二次加密数据再与第二组明文进行异或运算产生第二组密文,一次类推,直到加密完毕。

优点 :

1.隐藏了明文模式;

2.分组密码转化为流模式;

3.可以及时加密传送小于分组的数据;

缺点 :

1.不利于并行计算;

2. 对明文的主动攻击是可能的 ;

3. 误差传送:一个明文单元损坏影响多个单元 ;

 

 

 

5. 计数器模式–CTR

使用计数器,计数器初始值加密后与第一组明文进行异或运算产生第一组密文,

计数器增加,然后,加密后与下一组明文进行异或运算产生下一组密文,以此类推,直到加密完毕

优点 :

1. 可并行计算 ;

2. 安全性至少与CBC 模式一样好 ;

3. 加密与解仅涉及密码算法的加密 ;

缺点 :

1. 没有错误传播,不易确保数据完整性 ;

  

分组密码填充方式简介

PKCS5 : 填充字符串由一个值为 5 的字节序列组成,每个字节填充该字节序列的长度。 明确定义 Block 的大小是 8 位

PKCS7 : 填充字符串由一个值为 7 的字节序列组成,每个字节填充该字节序列的长度。 对于块的大小是不确定的,可以在 1-255 之间

ISO10126: 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节填充随机数据。  

转自:http://aub.iteye.com/blog/1129339

9月 162015
 

一篇关于https原理的分析文章,虽然自己不能完全理解,但有收获,分享下

1 前言

百度已经于近日上线了全站 HTTPS 的安全搜索,默认会将 HTTP 请求跳转成 HTTPS。本文重点介绍 HTTPS 协议, 并简单介绍部署全站 HTTPS 的意义。

 

2 HTTPS 协议概述

HTTPS 可以认为是 HTTP + TLS。HTTP 协议大家耳熟能详了,目前大部分 WEB 应用和网站都是使用 HTTP 协议传输的。

TLS 是传输层加密协议,它的前身是 SSL 协议,最早由 netscape 公司于 1995 年发布,1999 年经过 IETF 讨论和规范后,改名为 TLS。如果没有特别说明,SSL 和 TLS 说的都是同一个协议。

HTTP 和 TLS 在协议层的位置以及 TLS 协议的组成如下图:

pic1

图 1 TLS 协议格式

TLS 协议主要有五部分:应用数据层协议,握手协议,报警协议,加密消息确认协议,心跳协议。

TLS 协议本身又是由 record 协议传输的,record 协议的格式如上图最右所示。

 

目前常用的 HTTP 协议是 HTTP1.1,常用的 TLS 协议版本有如下几个:TLS1.2, TLS1.1, TLS1.0 和 SSL3.0。其中 SSL3.0 由于 POODLE 攻击已经被证明不安全,但统计发现依然有不到 1% 的浏览器使用 SSL3.0。TLS1.0 也存在部分安全漏洞,比如 RC4 和 BEAST 攻击。

TLS1.2 和 TLS1.1 暂时没有已知的安全漏洞,比较安全,同时有大量扩展提升速度和性能,推荐大家使用。

需要关注一点的就是 TLS1.3 将会是 TLS 协议一个非常重大的改革。不管是安全性还是用户访问速度都会有质的提升。不过目前没有明确的发布时间。

同时 HTTP2 也已经正式定稿,这个由 SPDY 协议演化而来的协议相比 HTTP1.1 又是一个非常重大的变动,能够明显提升应用层数据的传输效率。

 

3 HTTPS 功能介绍

百度使用 HTTPS 协议主要是为了保护用户隐私,防止流量劫持。

HTTP 本身是明文传输的,没有经过任何安全处理。例如用户在百度搜索了一个关键字,比如“苹果手机”,中间者完全能够查看到这个信息,并且有可能打电话过来骚扰用户。也有一些用户投诉使用百度时,发现首页或者结果页面浮了一个很长很大的广告,这也肯定是中间者往页面插的广告内容。如果劫持技术比较低劣的话,用户甚至无法访问百度。

这里提到的中间者主要指一些网络节点,是用户数据在浏览器和百度服务器中间传输必须要经过的节点。比如 WIFI 热点,路由器,防火墙,反向代理,缓存服务器等。

在 HTTP 协议下,中间者可以随意嗅探用户搜索内容,窃取隐私甚至篡改网页。不过 HTTPS 是这些劫持行为的克星,能够完全有效地防御。

总体来说,HTTPS 协议提供了三个强大的功能来对抗上述的劫持行为:

1,  内容加密。浏览器到百度服务器的内容都是以加密形式传输,中间者无法直接查看原始内容。

2,  身份认证。保证用户访问的是百度服务,即使被 DNS 劫持到了第三方站点,也会提醒用户没有访问百度服务,有可能被劫持

3,  数据完整性。防止内容被第三方冒充或者篡改。

那 HTTPS 是如何做到上述三点的呢?下面从原理角度介绍一下。

 

4 HTTPS 原理介绍

4.1 内容加密

加密算法一般分为两种,对称加密和非对称加密。所谓对称加密(也叫密钥加密)就是指加密和解密使用的是相同的密钥。而非对称加密(也叫公钥加密)就是指加密和解密使用了不同的密钥。

pic2

图 2 对称加密

pic3

图 3 非对称加密

对称内容加密强度非常高,一般破解不了。但存在一个很大的问题就是无法安全地生成和保管密钥。假如客户端软件和服务器之间每次会话都使用固定的,相同的密钥加密和解密,肯定存在很大的安全隐患。如果有人从客户端端获取到了对称密钥,整个内容就不存在安全性了,而且管理海量的客户端密钥也是一件很复杂的事情。

非对称加密主要用于密钥交换(也叫密钥协商),能够很好地解决这个问题。浏览器和服务器每次新建会话时都使用非对称密钥交换算法协商出对称密钥,使用这些对称密钥完成应用数据的加解密和验证,整个会话过程中的密钥只在内存中生成和保存,而且每个会话的对称密钥都不相同(除非会话复用),中间者无法窃取。

非对称密钥交换很安全,但同时也是 HTTPS 性能和速度严重降低的“罪魁祸首”。想要知道 HTTPS 为什么影响速度,为什么消耗资源,就一定要理解非对称密钥交换的整个过程。

下面重点介绍一下非对称密钥交换的数学原理及在 TLS 握手过程中的应用。

4.1.1 非对称密钥交换

在非对称密钥交换算法出现以前,对称加密一个很大的问题就是不知道如何安全生成和保管密钥。非对称密钥交换过程主要就是为了解决这个问题,使得对称密钥的生成和使用更加安全。

密钥交换算法本身非常复杂,密钥交换过程涉及到随机数生成,模指数运算,空白补齐,加密,签名等操作。

常见的密钥交换算法有 RSA,ECDHE,DH,DHE 等算法。它们的特性如下:

  •  RSA:算法实现简单,诞生于 1977 年,历史悠久,经过了长时间的破解测试,安全性高。缺点就是需要比较大的素数(目前常用的是 2048 位)来保证安全强度,很消耗 CPU 运算资源。RSA 是目前唯一一个既能用于密钥交换又能用于证书签名的算法。
  • DH:diffie-hellman 密钥交换算法,诞生时间比较早(1977 年),但是 1999 年才公开。缺点是比较消耗 CPU 性能。
  • ECDHE:使用椭圆曲线(ECC)的 DH 算法,优点是能用较小的素数(256 位)实现 RSA 相同的安全等级。缺点是算法实现复杂,用于密钥交换的历史不长,没有经过长时间的安全攻击测试。
  •  ECDH:不支持 PFS,安全性低,同时无法实现 false start。
  •  DHE:不支持 ECC。非常消耗 CPU 资源。

建议优先支持 RSA 和 ECDH_RSA 密钥交换算法。原因是:

1,  ECDHE 支持 ECC 加速,计算速度更快。支持 PFS,更加安全。支持 false start,用户访问速度更快。

2,  目前还有至少 20% 以上的客户端不支持 ECDHE,我们推荐使用 RSA 而不是 DH 或者 DHE,因为 DH 系列算法非常消耗 CPU(相当于要做两次 RSA 计算)。

pic4

需要注意通常所说的 ECDHE 密钥交换默认都是指 ECDHE_RSA,使用 ECDHE 生成 DH 算法所需的公私钥,然后使用 RSA 算法进行签名最后再计算得出对称密钥。

非对称加密相比对称加密更加安全,但也存在两个明显缺点:

1,  CPU 计算资源消耗非常大。一次完全 TLS 握手,密钥交换时的非对称解密计算量占整个握手过程的 90% 以上。而对称加密的计算量只相当于非对称加密的 0.1%,如果应用层数据也使用非对称加解密,性能开销太大,无法承受。

2,  非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是 2048 位,意味着待加密内容不能超过 256 个字节。

所以公钥加密目前只能用来作密钥交换或者内容签名,不适合用来做应用层传输内容的加解密。

非对称密钥交换算法是整个 HTTPS 得以安全的基石,充分理解非对称密钥交换算法是理解 HTTPS 协议和功能的关键。

下面分别通俗地介绍一下 RSA 和 ECDHE 在密钥交换过程中的应用。

4.1.1.1 RSA 密钥协商

4.1.1.1.1 RSA 算法介绍

RSA 算法的安全性是建立在乘法不可逆或者大数因子很难分解的基础上。RSA 的推导和实现涉及到了欧拉函数和费马定理及模反元素的概念,有兴趣的读者可以自行百度。

RSA 算法是统治世界的最重要算法之一,而且从目前来看,RSA 也是 HTTPS 体系中最重要的算法,没有之一。

RSA 的计算步骤如下:

1,  随机挑选两个质数 p, q,假设 p = 13, q = 19。 n = p * q = 13 * 19 = 247;

2,  ∅(n) 表示与整数 n 互质数的个数。如果 n 等于两个质数的积,则∅(n)=(p-1)(q-1) 挑选一个数 e,满足 1< e <∅(n) 并且 e 与互质,假设 e = 17;

3,  计算 e 关于 n 的模反元素, ed=1 mod ∅(n) , 由 e = 17 ,∅(n) =216  可得 d = 89;

4,  求出了 e,和 d,假设明文 m = 135,密文用 c 表示。那么加解密计算如下:

scr1

实际应用中,(n,e) 组成了公钥对,(n,d)组成了私钥对,其中 n 和 d 都是一个接近 22048的大数。即使现在性能很强的 CPU,想要计算 m≡c^d mod(n),也需要消耗比较大的计算资源和时间。

公钥对 (n, e) 一般都注册到了证书里,任何人都能直接查看,比如百度证书的公钥对如下图,其中最末 6 个数字(010001)换算成 10 进制就是 65537,也就是公钥对中的 e。e 取值比较小的好处有两个:

1,  由 c=m^e mod(n) 可知,e 较小,客户端 CPU 计算消耗的资源较少。

2,  加大 server 端的破解难度。e 比较小,私钥对中的 d 必然会非常大。所以 d 的取值空间也就非常大,增加了破解难度。

那为什么 (n,e) 能做为公钥公开,甚至大家都能直接从证书中查看到,这样安全吗?分析如下:

由于 ed≡1 mod ∅(n),知道了 e 和 n,想要求出私钥 d,就必须知道∅(n)。而∅(n)=(p-1)*(q-1),必须计算出 p 和 q 才能确定私钥 d。但是当 n 大到一定程度时(比如接近 2^2048),即使现在最快的 CPU 也无法进行这个因式分解,即无法知道 n 是由哪个数 p 和 q 乘出来的。所以就算知道了公钥,整个加解密过程还是非常安全的。

pic5

图 5 百度 HTTPS 证书公钥

4.1.1.1.2 握手过程中的 RSA 密钥协商

介绍完了 RSA 的原理,那最终会话所需要的对称密钥是如何生成的呢?跟 RSA 有什么关系?

以 TLS1.2 为例简单描述一下,省略跟密钥交换无关的握手消息。过程如下:

1,  浏览器发送 client_hello,包含一个随机数 random1。

2,  服务端回复 server_hello,包含一个随机数 random2,同时回复 certificate,携带了证书公钥 P。

3,  浏览器接收到 random2 之后就能够生成 premaster_secrect 以及 master_secrect。其中 premaster_secret 长度为 48 个字节,前 2 个字节是协议版本号,剩下的 46 个字节填充一个随机数。结构如下:

Struct {byte Version[2];bute random[46];}

master secrect 的生成算法简述如下:

Master_key = PRF(premaster_secret, “master secrect”, 随机数1+随机数2)其中 PRF 是一个随机函数,定义如下:PRF(secret, label, seed) = P_MD5(S1, label + seed)  XOR  P_SHA-1(S2, label + seed)

从上式可以看出,把 premaster_key 赋值给 secret,”master key”赋值给 label,浏览器和服务器端的两个随机数做种子就能确定地求出一个 48 位长的随机数。

而 master secrect 包含了六部分内容,分别是用于校验内容一致性的密钥,用于对称内容加解密的密钥,以及初始化向量(用于 CBC 模式),客户端和服务端各一份。

至此,浏览器侧的密钥已经完成协商。

4,  浏览器使用证书公钥 P 将 premaster_secrect 加密后发送给服务器。

5,  服务端使用私钥解密得到 premaster_secrect。又由于服务端之前就收到了随机数 1,所以服务端根据相同的生成算法,在相同的输入参数下,求出了相同的 master secrect。

RSA 密钥协商握手过程图示如下:

PIC2

图 6 RSA 密钥协商过程

可以看出,密钥协商过程需要 2 个 RTT,这也是 HTTPS 慢的一个重要原因。而 RSA 发挥的关键作用就是对 premaster_secrect 进行了加密和解密。中间者不可能破解 RSA 算法,也就不可能知道 premaster_secrect,从而保证了密钥协商过程的安全性。

4.1.1.2 ECDHE 密钥协商

4.1.1.2.1 DH 与 ECC 算法原理

ECDHE 算法实现要复杂很多,主要分为两部分:diffie-hellman 算法(简称为 DH)及 ECC(椭圆曲线算术)。他们的安全性都是建立在离散对数计算很困难的基础上。

简单介绍一下 dh 算法的实现,先介绍两个基本概念:

  • 本原根:如果整数 a 是素数 p 的本原根,则 a, a^2, …, a^(p-1) 在 mod p 下都不相同。
  •  离散对数:对任意整数 b 和素数 p 的本原根 a,存在唯一的指数 i 满足:

b ≡ a^i mod p (0≤i≤p-1)

则称 i 是 b 的以 a 为底的模 p 的离散对数。

理解这两个概念,dh 算法就非常简单了,示例如下:

假设 client 和 server 需要协商密钥,p=2579,则本原根 a = 2。

1,  Client 选择随机数 Kc = 123 做为自己的私钥,计算 Yc = a^Kc  mod p = 2^123 mod 2579 = 2400,把 Yc 作为公钥发送给 server。

2,  Server 选择随机数 Ks = 293 作为私钥,计算 Ys = a^Ks  mod p = s^293 mod 2579 = 968,把 Ys 作为公钥发送给 client。

3,  Client 计算共享密钥:secrect =  Ys^Kc mod (p) = 968^123  mod(2579) = 434

4,  Server 计算共享密钥:secrect = Yc^Ks mod(p) =2400^293 mod(2579) =434

上述公式中的 Ys,Yc,P, a, 都是公开信息,可以被中间者查看,只有 Ks,Kc 作为私钥没有公开,当私钥较小时,通过穷举攻击能够计算出共享密钥,但是当私钥非常大时,穷举攻击肯定是不可行的。

DH 算法有一个比较大的缺陷就是需要提供足够大的私钥来保证安全性,所以比较消耗 CPU 计算资源。ECC 椭圆曲线算术能够很好的解决这个问题,224 位的密钥长度就能达到 RSA2048 位的安全强度。

ECC 的曲线公式描述的其实不是椭圆,只是跟椭圆曲线周长公式形似才叫椭圆曲线加密算术。ECC 涉及到了有限域、群等近世代数的多个概念,就不做详细介绍了。

ECC 安全性依赖于这样一个事实:

P = kQ, 已知 k, Q 求出 P 相对简单,但是已知 P 和 Q 求出 k 却非常困难。

上式看起来非常简单,但有如下约束条件:

1,  Q 是一个非常大的质数,p, k, q 都是椭圆曲线有限域上的离散点。

2,  有限域定义了自己的加法和乘法法则,即使 kQ 的运算也非常复杂。

ECC 应用于 Diffie-Hellman 密钥交换过程如下:

1,  定义一个满足椭圆方程的有限域,即挑选 p, a, b 满足如下方程:

y^2 mod p = (x^3+ax +b) mod p

2,  挑选基点 G = (x, y),G 的阶为 n。n 为满足 nG = 0 的最小正整数。

3,  Client 选择私钥 Kc (0 <Kc<n ),产生公钥 Yc =Kc *G

4,  server 选择私钥 Ks 并产生公钥 Ys =Ks*G

5,  client 计算共享密钥 K = Kc*Ys   ,server 端计算共享密钥 Ks*Yc ,这两者的结果是一样的,因为:

 Kc*Ys = Kc*(Ks*G) = Ks*(Kc*G) = Ks*Yc

由上面描述可知,只要确定 p, a, b 就能确定一条有限域上的椭圆曲线,由于不是所有的椭圆曲线都能够用于加密,所以 p, a, b 的选取非常讲究,直接关系曲线的安全性和计算速度。

Openssl 实现的,也是 FIPS 推荐的 256 位素数域上的椭圆曲线参数定义如下:

质数 p = 115792089210356248762697446949407573530086143415290314195533631308867097853951 阶 n = 115792089210356248762697446949407573529996955224135760342422259061068512044369SEED = c49d3608 86e70493 6a6678e1 139d26b7 819f7e90c = 7efba166 2985be94 03cb055c 75d4f7e0 ce8d84a9 c5114abcaf317768 0104fa0d 椭圆曲线的系数 a = 0 椭圆曲线的系统 b = 5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f63bce3c3e 27d2604b 基点 G x = 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0f4a13945 d898c296 基点 G y = 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ececbb64068 37bf51f5

 

4.1.1.2.2 握手过程中的 ECDHE 密钥协商

简单介绍了 ECC 和 DH 算法的数学原理,我们看下 ECDHE 在 TLS 握手过程中的应用。

相比 RSA,ECDHE 需要多发送一个 server_key_exchange 的握手消息才能完成密钥协商。

同样以 TLS1.2 为例,简单描述一下过程:

1,  浏览器发送 client_hello,包含一个随机数 random1,同时需要有 2 个扩展:

a)         Elliptic_curves:客户端支持的曲线类型和有限域参数。现在使用最多的是 256 位的素数域,参数定义如上节所述。

b)        Ec_point_formats:支持的曲线点格式,默认都是 uncompressed。

2,  服务端回复 server_hello,包含一个随机数 random2 及 ECC 扩展。

3,  服务端回复 certificate,携带了证书公钥。

4,  服务端生成 ECDH 临时公钥,同时回复 server_key_exchange,包含三部分重要内容:

a)         ECC 相关的参数。

b)        ECDH 临时公钥。

c)         ECC 参数和公钥生成的签名值,用于客户端校验。

5,  浏览器接收 server_key_exchange 之后,使用证书公钥进行签名解密和校验,获取服务器端的 ECDH 临时公钥,生成会话所需要的共享密钥。

至此,浏览器端完成了密钥协商。

6,  浏览器生成 ECDH 临时公钥和 client_key_exchange 消息,跟 RSA 密钥协商不同的是,这个消息不需要加密了。

7,  服务器处理 client_key_exchang 消息,获取客户端 ECDH 临时公钥。

8,  服务器生成会话所需要的共享密钥。

9,  Server 端密钥协商过程结束。

 

图示如下:

PIC1

图 7 ECDHE 密钥协商过程

4.1.2 对称内容加密

非对称密钥交换过程结束之后就得出了本次会话需要使用的对称密钥。对称加密又分为两种模式:流式加密和分组加密。流式加密现在常用的就是 RC4,不过 RC4 已经不再安全,微软也建议网站尽量不要使用 RC4 流式加密

一种新的替代 RC4 的流式加密算法叫 ChaCha20,它是 google 推出的速度更快,更安全的加密算法。目前已经被 android 和 chrome 采用,也编译进了 google 的开源 openssl 分支 —boring ssl,并且nginx 1.7.4 也支持编译 boringssl

分组加密以前常用的模式是 AES-CBC,但是 CBC 已经被证明容易遭受BEASTLUCKY13 攻击。目前建议使用的分组加密模式是 AES-GCM,不过它的缺点是计算量大,性能和电量消耗都比较高,不适用于移动电话和平板电脑。

4.2 身份认证

身份认证主要涉及到 PKI 和数字证书。通常来讲 PKI(公钥基础设施)包含如下部分:

  • End entity:终端实体,可以是一个终端硬件或者网站。
  • CA:证书签发机构。
  • RA:证书注册及审核机构。比如审查申请网站或者公司的真实性。
  • CRL issuer:负责证书撤销列表的发布和维护。
  • Repository:负责数字证书及 CRL 内容存储和分发。

申请一个受信任的数字证书通常有如下流程:

1,  终端实体生成公私钥和证书请求。

2,  RA 检查实体的合法性。如果个人或者小网站,这一步不是必须的。

3,  CA 签发证书,发送给申请者。

4,  证书更新到 repository,终端后续从 repository 更新证书,查询证书状态等。

目前百度使用的证书是 X509v3 格式,由如下三个部分组成:

1,  tbsCertificate(to be signed certificate 待签名证书内容),这部分包含了 10 个要素,分别是版本号,序列号,签名算法标识,发行者名称,有效期,证书主体名,证书主体公钥信息,发行商唯一标识,主体唯一标识,扩展等。

2,  signatureAlgorithm,签名算法标识,指定对 tbsCertificate 进行签名的算法。

3,  signaturValue(签名值),使用 signatureAlgorithm 对 tbsCertificate 进行计算得到签名值。

数字证书有两个作用:

1,  身份授权。确保浏览器访问的网站是经过 CA 验证的可信任的网站。

2,  分发公钥。每个数字证书都包含了注册者生成的公钥。在 SSL 握手时会通过 certificate 消息传输给客户端。比如前文提到的 RSA 证书公钥加密及 ECDHE 的签名都是使用的这个公钥。

申请者拿到 CA 的证书并部署在网站服务器端,那浏览器发起握手接收到证书后,如何确认这个证书就是 CA 签发的呢?怎样避免第三方伪造这个证书?

答案就是数字签名(digital signature)。数字签名是证书的防伪标签,目前使用最广泛的 SHA-RSA 数字签名的制作和验证过程如下:

1,  数字签名的签发。首先是使用哈希函数对待签名内容进行安全哈希,生成消息摘要,然后使用 CA 自己的私钥对消息摘要进行加密。

2,  数字签名的校验。使用 CA 的公钥解密签名,然后使用相同的签名函数对待签名证书内容进行签名并和服务端数字签名里的签名内容进行比较,如果相同就认为校验成功。

pic8

图 8 数字签名生成及校验

这里有几点需要说明:

  1. 数字签名签发和校验使用的密钥对是 CA 自己的公私密钥,跟证书申请者提交的公钥没有关系。
  2. 数字签名的签发过程跟公钥加密的过程刚好相反,即是用私钥加密,公钥解密。
  3. 现在大的 CA 都会有证书链,证书链的好处一是安全,保持根 CA 的私钥离线使用。第二个好处是方便部署和撤销,即如果证书出现问题,只需要撤销相应级别的证书,根证书依然安全。
  4. 根 CA 证书都是自签名,即用自己的公钥和私钥完成了签名的制作和验证。而证书链上的证书签名都是使用上一级证书的密钥对完成签名和验证的。
  5. 怎样获取根 CA 和多级 CA 的密钥对?它们是否可信?当然可信,因为这些厂商跟浏览器和操作系统都有合作,它们的公钥都默认装到了浏览器或者操作系统环境里。比如firefox 就自己维护了一个可信任的 CA 列表,而chrome 和 IE 使用的是操作系统的 CA 列表

4.3 数据完整性

这部分内容比较好理解,跟平时的 md5 签名类似,只不过安全要求要高很多。openssl 现在使用的完整性校验算法有两种:MD5 或者 SHA。由于 MD5 在实际应用中存在冲突的可能性比较大,所以尽量别采用 MD5 来验证内容一致性。SHA 也不能使用 SHA0 和 SHA1,中国山东大学的王小云教授在 2005 年就宣布破解了 SHA-1 完整版算法

微软和 google 都已经宣布 16 年及 17 年之后不再支持 sha1 签名证书。

 

5 HTTPS 使用成本

HTTPS 目前唯一的问题就是它还没有得到大规模应用,受到的关注和研究都比较少。至于使用成本和额外开销,完全不用太过担心。

一般来讲,使用 HTTPS 前大家可能会非常关注如下问题:

  1. 证书费用以及更新维护。大家觉得申请证书很麻烦,证书也很贵,可是证书其实一点都不贵,便宜的一年几十块钱,最多也就几百。而且现在也有了免费的证书机构,比如著名的 mozilla 发起的免费证书项目:let’s encrypt(https://letsencrypt.org/)就支持免费证书安装和自动更新。这个项目将于今年中旬投入正式使用。

数字证书的费用其实也不高,对于中小网站可以使用便宜甚至免费的数字证书服务(可能存在安全隐患),像著名的 verisign 公司的证书一般也就几千到几万块一年不等。当然如果公司对证书的需求比较大,定制性要求高,可以建立自己的 CA 站点,比如 google,能够随意签发 google 相关证书。

  1. HTTPS 降低用户访问速度。HTTPS 对速度会有一定程度的降低,但是只要经过合理优化和部署,HTTPS 对速度的影响完全可以接受。在很多场景下,HTTPS 速度完全不逊于 HTTP,如果使用 SPDY,HTTPS 的速度甚至还要比 HTTP 快。

大家现在使用百度 HTTPS 安全搜索,有感觉到慢吗?

  1. HTTPS 消耗 CPU 资源,需要增加大量机器。前面介绍过非对称密钥交换,这是消耗 CPU 计算资源的大户,此外,对称加解密,也需要 CPU 的计算。

同样地,只要合理优化,HTTPS 的机器成本也不会明显增加。对于中小网站,完全不需要增加机器也能满足性能需求。

6 后记

国外的大型互联网公司很多已经启用了全站 HTTPS,这也是未来互联网的趋势。国内的大型互联网并没有全站部署 HTTPS,只是在一些涉及账户或者交易的子页面 / 子请求上启用了 HTTPS。百度搜索首次全站部署 HTTPS,对国内互联网的全站 HTTPS 进程必将有着巨大的推动作用。

目前互联网上关于 HTTPS 的中文资料比较少,本文就着重介绍了 HTTPS 协议涉及到的重要知识点和平时不太容易理解的盲区,希望能对大家理解 HTTPS 协议有帮助。百度 HTTPS 性能优化涉及到大量内容,从前端页面、后端架构、协议特性、加密算法、流量调度、架构和运维、安全等方面都做了大量工作。本系列的文章将一一进行介绍。

转自:http://op.baidu.com/2015/04/https-s01a01/

9月 162015
 

通俗易懂的数字签名和数字证书介绍。

1.

鲍勃有两把钥匙,一把是公钥,另一把是私钥。

2.

鲍勃把公钥送给他的朋友们—-帕蒂、道格、苏珊—-每人一把。

3.

苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。

4.

鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。

5.

鲍勃给苏珊回信,决定采用”数字签名”。他写完后先用Hash函数,生成信件的摘要(digest)。

6.

然后,鲍勃使用私钥,对这个摘要加密,生成”数字签名”(signature)。

7.

鲍勃将这个签名,附在信件下面,一起发给苏珊。

8.

苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。

9.

苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

10.

复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成”数字签名”,写信给苏珊,让苏珊用假的鲍勃公钥进行解密。

11.

后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找”证书中心”(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成”数字证书”(Digital Certificate)。

12.

鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。

13.

苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明”数字签名”是否真的是鲍勃签的。

14.

下面,我们看一个应用”数字证书”的实例:https协议。这个协议主要用于网页加密。

15.

首先,客户端向服务器发出加密请求。

16.

服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。

17.

客户端(浏览器)的”证书管理器”,有”受信任的根证书颁发机构”列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。

18.

如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。

19.

如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。

20.

如果数字证书是可靠的,客户端就可以使用证书中的服务器公钥,对信息进行加密,然后与服务器交换加密信息。

来自:http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

6月 162015
 

好文章一起分享下:http://www.gaojinbo.com/openssl-%E7%94%9F%E6%88%90%E8%87%AA%E7%AD%BE%E8%AF%81%E4%B9%A6.html

要生成证书的目录下建立几个文件和文件夹,有./demoCA/ ./demoCA/newcerts/  ./demoCA/index.txt ./demoCA/serial,在serial文件中写入第一个序列号“01”

1.生成X509格式的CA自签名证书 
$openssl req -new -x509 -keyout ca.key -out ca.crt

 

2.生成服务端的私钥(key文件)及csr 文件 
$openssl genrsa -des3 -out server.key 1024 
$openssl req -new -key server.key -out server.csr

 

3.生成客户端的私钥(key文件)及csr文件 
$openssl genrsa -des3 -out client.key 1024 
$openssl req -new -key client.key -out client.csr

 

4.用生成的CA的证书为刚才生成的server.csr,client.csr文件签名 
$openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key 
$openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key

 

5. 生成p12格式证书 
$openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx 
$openssl pkcs12 -export -inkey server.key -in server.crt -out server.pfx

 

6.生成pem格式证书 
有时需要用到pem格式的证书,可以用以下方式合并证书文件(crt)和私钥文件(key)来生成 
$cat client.crt client.key> client.pem 
$cat server.crt server.key > server.pem

 

7.PFX文件转换为X509证书文件和RSA密钥文件 
$openssl pkcs12 -in server.pfx -nodes -out server.pem 
$openssl rsa -in server.pem -out server2.key 
$openssl x509 -in server.pem -out server2.crt

 

这样生成服务端证书:ca.crt, server.key, server.crt, server.pem, server.pfx,客户端证书:ca.crt, client.key, client.crt, client.pem, client.pfx

6月 122015
 

生成keystore文件

keytool -genkey -alias test -keyalg RSA -keystore /key.store

RSA是一个既能用于数据加密也能用于数字签名的算法。
DSA(Digital Signature Algorithm,数字签名算法,用作数字签名标准的一部分),它是另一种公开密钥算法,它不能用作加密,只用作数字签名。DSA使用公开密钥,为接受者验证数据的完整性和数据发送者的身份。

提取证书的方法:
keytool -export -alias 别名 -keystore 文件名 -file 证书名称

但是我们无法通过KEYTOOL工具来提取私钥的..我们只能通过java的KeyStore类getEntry() 或者getKey()来提取私钥.

1. 导出私钥参考下面例子中的export方法

2. 怎么来验证提取的私钥是否正确呢 (因为公钥私钥必须成对出现,我们可以通过证书提取去公钥,然后用公钥加密,使用刚刚获得的私钥解密) ,参考代码中check方法

代码如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

import javax.crypto.Cipher;

import sun.misc.BASE64Encoder;

public class ExportPrivateKey {
private File keystoreFile;
private String keyStoreType;
private char[] password;
private String alias;
private File exportedFile;

public static KeyPair getPrivateKey(KeyStore keystore, String alias,
char[] password) {
try {
Key key = keystore.getKey(alias, password);
if (key instanceof PrivateKey) {
Certificate cert = keystore.getCertificate(alias);
PublicKey publicKey = cert.getPublicKey();
return new KeyPair(publicKey, (PrivateKey) key);
}
} catch (UnrecoverableKeyException e) {
} catch (NoSuchAlgorithmException e) {
} catch (KeyStoreException e) {
}
return null;
}

public void export() throws Exception {
KeyStore keystore = KeyStore.getInstance(keyStoreType);
BASE64Encoder encoder = new BASE64Encoder();
keystore.load(new FileInputStream(keystoreFile), password);
KeyPair keyPair = getPrivateKey(keystore, alias, password);
PrivateKey privateKey = keyPair.getPrivate();
String encoded = encoder.encode(privateKey.getEncoded());
FileWriter fw = new FileWriter(exportedFile);
fw.write(“—–BEGIN RSA PRIVATE KEY—–n”);
fw.write(encoded);
fw.write(“n”);
fw.write(“—–END RSA PRIVATE KEY—–“);
fw.close();
}

public void check(){
//通过证书,获取公钥
 CertificateFactory cf;
try {
cf = CertificateFactory.getInstance(“X.509”);
FileInputStream in = new FileInputStream(“/home/ouu/keystore/server.cer”);
//生成一个证书对象并使用从输入流 inStream 中读取的数据对它进行初始化。
Certificate c = cf.generateCertificate(in);
PublicKey publicKey = c.getPublicKey();

       KeyStore keystore = KeyStore.getInstance(keyStoreType);
BASE64Encoder encoder = new BASE64Encoder();
keystore.load(new FileInputStream(keystoreFile), password);
KeyPair keyPair = getPrivateKey(keystore, alias, password);
PrivateKey privateKey = keyPair.getPrivate();

//通过下面这段代码提取的私钥是否正确
String before = “asdf”;
       byte[] plainText = before.getBytes(“UTF-8”);
       Cipher cipher = Cipher.getInstance(“RSA/ECB/PKCS1Padding”);
       cipher.init(Cipher.ENCRYPT_MODE, publicKey);
       // 用公钥进行加密,返回一个字节流
       byte[] cipherText = cipher.doFinal(plainText);
       cipher.init(Cipher.DECRYPT_MODE, privateKey);
       // 用私钥进行解密,返回一个字节流
       byte[] newPlainText = cipher.doFinal(cipherText);
       System.out.println(new String(newPlainText, “UTF-8”)); 
       
       

       

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void main(String args[]) throws Exception {
ExportPrivateKey export = new ExportPrivateKey();
export.keystoreFile = new File(
“/home/ouu/keystore/server.keystore”);
export.keyStoreType = “JKS”;
export.password = “123456”.toCharArray();
export.alias = “server”;
export.exportedFile = new File(“server.key”);
export.export(); //导出私钥匙
export.check();  //检测私钥正确性
}
}







6月 082015
 

网上整理的一些数字证书格式及资料说明.

cer后缀的证书文件有两种编码–>DER二进制编码或者BASE64编码(也就是.pem)

p7b一般是证书链,里面包括1到多个证书
pfx是指以pkcs#12格式存储的证书和相应私钥。

在Security编程中,有几种典型的密码交换信息文件格式:
DER-encoded certificate: .cer, .crt
PEM-encoded message: .pem
PKCS#12 Personal Information Exchange: .pfx, .p12
PKCS#10 Certification Request: .p10
PKCS#7 cert request response: .p7r
PKCS#7 binary message: .p7b

.cer/.crt是用于存放证书,它是2进制形式存放的,不含私钥。
.pem跟crt/cer的区别是它以Ascii来表示。
pfx/p12用于存放个人证书/私钥,他通常包含保护密码,2进制方式
p10是证书请求
p7r是CA对证书请求的回复,只用于导入
p7b以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥。

其中,我介绍如何从p12/pfx文件中提取密钥对及其长度:
1,首先,读取pfx/p12文件(需要提供保护密码)
2,通过别名(Alias,注意,所有证书中的信息项都是通过Alias来提取的)提取你想要分析的证书链
3,再将其转换为一个以X509证书结构体
4,提取里面的项,如果那你的证书项放在第一位(单一证书),直接读取 x509Certs[0](见下面的代码)这个X509Certificate对象
5,X509Certificate对象有很多方法,tain198127网友希望读取RSA密钥(公私钥)及其长度(见http://www.matrix.org.cn/thread.shtml?topicId=43786&forumId=55&#reply),那真是太Easy了,
            X509Certificate keyPairCert = x509Certs[0];
            int iKeySize = X509CertUtil.getCertificateKeyLength(keyPairCert);
            System.out.println(“证书密钥算法=”+keyPairCert.getPublicKey().getAlgorithm());
            System.out.println(“证书密钥长度=”+iKeySize);

提取了他所需要的信息。

 

X.509定义了两种证书:公钥证书和属性证书   
  PKCS#7和PKCS#12使用的都是公钥证书   
  PKCS#7的SignedData的一种退化形式可以分发公钥证书和CRL   
  一个SignedData可以包含多张公钥证书   
  PKCS#12可以包含公钥证书及其私钥,也可包含整个证书链   


简介
Java自带的keytool工具是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务。它还允许用户储存他们的通信对等者的公钥(以证书形式)。

keytool 将密钥和证书储存在一个所谓的密钥仓库(keystore)中。缺省的密钥仓库实现将密钥仓库实现为一个文件。它用口令来保护私钥。

Java KeyStore的类型
JKS和JCEKS是Java密钥库(KeyStore)的两种比较常见类型(我所知道的共有5种,JKS, JCEKS, PKCS12, BKS,UBER)。

JKS的Provider是SUN,在每个版本的JDK中都有,JCEKS的Provider是SUNJCE,1.4后我们都能够直接使用它。

JCEKS在安全级别上要比JKS强,使用的Provider是JCEKS(推荐),尤其在保护KeyStore中的私钥上(使用TripleDes)。

PKCS#12是公钥加密标准,它规定了可包含所有私钥、公钥和证书。其以二进制格式存储,也称为 PFX 文件,在windows中可以直接导入到密钥区,注意,PKCS#12的密钥库保护密码同时也用于保护Key。

BKS 来自BouncyCastle Provider,它使用的也是TripleDES来保护密钥库中的Key,它能够防止证书库被不小心修改(Keystore的keyentry改掉1个 bit都会产生错误),BKS能够跟JKS互操作,读者可以用Keytool去TryTry。

UBER比较特别,当密码是通过命令行提供的时候,它只能跟keytool交互。整个keystore是通过PBE/SHA1/Twofish加密,因此keystore能够防止被误改、察看以及校验。以前,Sun JDK(提供者为SUN)允许你在不提供密码的情况下直接加载一个Keystore,类似cacerts,UBER不允许这种情况。

证书导入
Der/Cer证书导入:

要从某个文件中导入某个证书,使用keytool工具的-import命令:

keytool -import -file mycert.der -keystore mykeystore.jks

如果在 -keystore 选项中指定了一个并不存在的密钥仓库,则该密钥仓库将被创建。

如果不指定 -keystore 选项,则缺省密钥仓库将是宿主目录中名为 .keystore 的文件。如果该文件并不存在,则它将被创建。

创建密钥仓库时会要求输入访问口令,以后需要使用此口令来访问。可使用-list命令来查看密钥仓库里的内容:

keytool -list -rfc -keystore mykeystore.jks

 


P12格式证书导入:

keytool无法直接导入PKCS12文件。

第一种方法是使用IE将pfx证书导入,再导出为cert格式文件。使用上面介绍的方法将其导入到密钥仓库中。这样的话仓库里面只包含了证书信息,没有私钥内容。


第二种方法是将pfx文件导入到IE浏览器中,再导出为pfx文件。
       新生成的pfx不能被导入到keystore中,报错:keytool错误: java.lang.Exception: 所输入的不是一个 X.509 认证。新生成的pfx文件可以被当作keystore使用。但会报个错误as unknown attr1.3.6.1.4.1.311.17.1,查了下资料,说IE导出的就会这样,使用Netscape就不会有这个错误.

第三种方法是将pfx文件当作一个keystore使用。但是通过微软的证书管理控制台生成的pfx文件不能直接使用。keytool不认此格式,报keytool错误: java.io.IOException: failed to decrypt safe contents entry。需要通过OpenSSL转换一下:

1)openssl pkcs12 -in mycerts.pfx -out mycerts.pem

2)openssl pkcs12 -export -in mycerts.pem -out mykeystore.p12

通过keytool的-list命令可检查下密钥仓库中的内容:

keytool -rfc -list -keystore mykeystore.p12 -storetype pkcs12

这里需要指明仓库类型为pkcs12,因为缺省的类型为jks。这样此密钥仓库就即包含证书信息也包含私钥信息。

P7B格式证书导入:

keytool无法直接导入p7b文件。

需要将证书链RootServer.p7b(包含根证书)导出为根rootca.cer和子rootcaserver.cer 。

将这两个证书导入到可信任的密钥仓库中。

keytool -import -alias rootca -trustcacerts -file rootca.cer -keystore testkeytrust.jks

遇到是否信任该证书提示时,输入y

keytool -import -alias rootcaserver -trustcacerts -file rootcaserver.cer -keystore testkeytrust.jks

 


总结:

1)P12格式的证书是不能使用keytool工具导入到keystore中的

2)The Sun’s PKCS12 Keystore对从IE和其他的windows程序生成的pfx格式的证书支持不太好.

3)P7B证书链不能直接导入到keystore,需要将里面的证书导出成cer格式,再分别导入到keystore。

以下来自百度百科资料:

数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名。数字证书还有一个重要的特征就是只在特定的时间段内有效。
数字证书是一种权威性的电子文档,可以由权威公正的第三方机构,即CA(例如中国各地方的CA公司)中心签发的证书,也可以由企业级CA系统进行签发。
它以数字证书为核心的加密技术(加密传输、数字签名、数字信封等安全技术)可以对网络上传输的信息进行加密和解密、数字签名和签名验证,确保网上传递信息的机密性、完整性及交易的不可抵赖性。使用了数字证书,即使您发送的信息在网上被他人截获,甚至您丢失了个人的账户、密码等信息,仍可以保证您的账户、资金安全。
它是能提供在 Internet 上进行身份验证的一种权威性电子文档,人们可以在互联网交往中用它来证明自己的身份和识别对方的身份。当然在数字证书认证的过程中证书认证中心(CA)作为权威的,公正的,可信赖的第三方,其作用是至关重要的。如何判断数字认证中心公正第三方的地位是权威可信的?截至2014年3月11日,国家工业和信息化部以资质合规的方式,陆续向30多家相关机构颁发了从业资质。
由于 Internet 电子商务系统技术使得顾客在网上购物时能够极其方便地获得商家和企业的信息,但同时也增加了对某些敏感或有价值的数据被滥用的风险。为了保证互联网上电子交易及支付的安全性,保密性等,防范交易及支付过程中的欺诈行为,必须在网上建立一种信任机制。这就要求参加电子商务的买方和卖方都必须拥有合法的身份,并且在网上能够有效无误的被进行验证。
数字证书可用于:发送安全电子邮件、访问安全站点、网上证券交易、网上招标采购、网上办公、网上保险、网上税务、网上签约和网上银行等安全电子事务处理和安全电子交易活动。

原理

数字证书里存有很多数字和英文,当使用数字证书进行身份认证时,它将随机生成128位的身份码,每份数字证书都能生成相应但每次都不可能相同的数码,从而保证数据传输的保密性,即相当于生成一个复杂的密码。
数字证书绑定了公钥及其持有者的真实身份,它类似于现实生活中的居民身份证,所不同的是数字证书不再是纸质的证照,而是一段含有证书持有者身份信息并经过认证中心审核签发的电子数据,可以更加方便灵活地运用在电子商务和电子政务中。

特点

安全性
(1)为了避免传统数字证书方案中,由于使用不当造成的证书丢失等安全隐患,支付宝创造性的推出双证书解决方案:支付宝会员在申请数字证书时,将同时获得两张证书,一张用于验证支付宝账户,另一张用于验证会员当前所使用的计算机。 (2)第二张证书不能备份,会员必须为每一台计算机重新申请一张。这样即使会员的数字证书被他人非法窃取,仍可保证其账户不会受到损失。(3)支付盾是一个类似于U盘的实体安全工具,它内置的微型智能卡处理器能阻挡各种的风险,让您的账户始终处于安全的环境下。目为保证电子邮件安全性所使用的方式是数字证书。
唯一性
(1)支付宝数字证书根据用户身份给予相应的网络资源访问权限(2)申请使用数字证书后,如果在其他电脑登录支付宝账户,没有导入数字证书备份的情况下,只能查询账户,不能进行任何操作,这样就相当于您拥有了类似“钥匙”一样的数字凭证,增强账户使用安全。
方便性
(1)即时申请、即时开通、即时使用。(2)量身定制多种途径维护数字证书,例如通过短信,安全问题等。(3)不需要使用者掌握任何数字证书相关知识,也能轻松掌握。

2颁发过程

数字证书颁发过程一般为:用户首先产生自己的密钥对,并将公共密钥及部分个人身份信息传送给认证中心。认证中心在核实身份后,将执行一些必要的步骤,以确信请求确实由用户发送而来,然后,认证中心将发给用户一个数字证书,该证书内包含用户的个人信息和他的公钥信息,同时还附有认证中心的签名信息。用户就可以使用自己的数字证书进行相关的各种活动。数字证书由独立的证书发行机构发布。数字证书各不相同,每种证书可提供不同级别的可信度。可以从证书发行机构获得您自己的数字证书。

3相关作用

基于Internet网的电子商务系统技术使在网上购物的顾客能够极其方便轻松地获得商家和企业的信息,但同时也增加了对某些敏感或有价值的数据被滥用的风险。买方和卖方都必须对于在因特网上进行的一切金融交易运作都是真实可靠的,并且要使顾客、商家和企业等交易各方都具有绝对的信心,因而因特网(Internet)电子商务系统必须保证具有十分可靠的安全保密技术,也就是说,必须保证网络安全的四大要素,即信息传输的保密性、数据交换的完整性、发送信息的不可否认性、交易者身份的确定性。
信息的保密性
交易中的商务信息均有保密的要求。如信用卡的帐号和用户名被人知悉,就可能被盗用,订货和付款的信息被竞争对手获悉,就可能丧失商机。因此在电子商务的信息传播中一般均有加密的要求。
交易者身份的确定性
网上交易的双方很可能素昧平生,相隔千里。要使交易成功首先要能确认对方的身份,对商家要考虑客户端不能是骗子,而客户也会担心网上的商店不是一个玩弄欺诈的黑店。因此能方便而可靠地确认对方身份是交易的前提。对于为顾客或用户开展服务的银行、信用卡公司和销售商店,为了做到安全、保密、可靠地开展服务活动,都要进行身份认证的工作。对有关的销售商店来说,他们对顾客所用的信用卡的号码是不知道的,商店只能把信用卡的确认工作完全交给银行来完成。银行和信用卡公司可以采用各种保密与识别方法,确认顾客的身份是否合法,同时还要防止发生拒付款问题以及确认订货和订货收据信息等。
不可否认性
由于商情的千变万化,交易一旦达成是不能被否认的。否则必然会损害一方的利益。例如订购黄金,订货时金价较低,但收到订单后,金价上涨了,如收单方能否认受到订单的实际时间,甚至否认收到订单的事实,则订货方就会蒙受损失。因此电子交易通信过程的各个环节都必须是不可否认的。
不可修改性
交易的文件是不可被修改的,如上例所举的订购黄金。供货单位在收到订单后,发现金价大幅上涨了,如其能改动文件内容,将订购数1吨改为1克,则可大幅受益, 那么订货单位可能就会因此而蒙受损失。因此电子交易文件也要能做到不可修改,以保障交易的严肃和公正。
人们在感叹电子商务的巨大潜力的同时,不得不冷静地思考,在人与人互不见面的计算机互联网上进行交易和作业时,怎么才能保证交易的公正性和安全性,保证交易双方身份的真实性。国际上已经有比较成熟的安全解决方案,那就是建立安全证书体系结构。数字安全证书提供了一种在网上验证身份的方式。安全证书体制主要采用了公开密钥体制,其它还包括对称密钥加密、数字签名数字信封等技术。
我们可以使用数字证书,通过运用对称和非对称密码体制等密码技术建立起一套严密的身份认证系统,从而保证:信息除发送方和接收方外不被其它人窃取;信息在传输过程中不被篡改;发送方能够通过数字证书来确认接收方的身份;发送方对于自己的信息不能抵赖。

4授权机构

CA机构,又称为证书授证(Certificate Authority)中心,作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。CA中心为每个使用公开密钥的用户发放一个数字证书,数字证书的作用是证明证书中列出的用户合法拥有证书中列出的公开密钥。CA机构的数字签名使得攻击者不能伪造和篡改证书。它负责产生、分配并管理所有参与网上交易的个体所需的数字证书,因此是安全电子交易的核心环节。由此可见,建设证书授权(CA)中心,是开拓和规范电子商务市场必不可少的一步。为保证用户之间在网上传递信息的安全性、真实性、可靠性、完整性和不可抵赖性,不仅需要对用户的身份真实性进行验证,也需要有一个具有权威性、公正性、唯一性的机构,负责向电子商务的各个主体颁发并管理符合国内、国际安全电子交易协议标准的电子商务安全证书

5工作原理

数字证书采用公钥体制,即利用一对互相匹配的密钥进行加密解密。每个用户自己设定一把特定的仅为本人所知的私有密钥(私钥),用它进行解密和签名;同时设定一把公共密钥(公钥)并由本人公开,为一组用户所共享,用于加密和验证签名。当发送一份保密文件时,发送方使用接收方的公钥对数据加密,而接收方则使用自己的私钥解密,这样信息就可以安全无误地到达目的地了。通过数字的手段保证加密过程是一个不可逆过程,即只有用私有密钥才能解密。在公开密钥密码体制中,常用的一种是RSA体制。其数学原理是将一个大数分解成两个质数的乘积,加密和解密用的是两个不同的密钥。即使已知明文、密文和加密密钥(公开密钥),想要推导出解密密钥(私密密钥),在计算上是不可能的。按当下计算机技术水平,要破解1024位RSA密钥,需要上千年的计算时间。公开密钥技术解决了密钥发布的管理问题,商户可以公开其公开密钥,而保留其私有密钥。购物者可以用人人皆知的公开密钥对发送的信息进行加密,安全地传送给商户,然后由商户用自己的私有密钥进行解密。
用户也可以采用自己的私钥对信息加以处理,由于密钥仅为本人所有,这样就产生了别人无法生成的文件,也就形成了数字签名。采用数字签名,能够确认以下两点:
保证信息是由签名者自己签名发送的,签名者不能否认或难以否认。
保证信息自签发后到收到为止未曾作过任何修改,签发的文件是真实文件。

6数字签名

报文按双方约定的HASH算法计算得到一个固定位数的报文摘要。在数学上保证:只要改动报文中任何一位,重新计算出的报文摘要值就会与原先的值不相符。这样就保证了报文的不可更改性。
将该报文摘要值用发送者的私人密钥加密(对明文进行解密完全没问题,会得出一个不可读的“明文”),然后连同原报文一起发送给接收者,而“加密”后的报文即称数字签名
接收方收到数字签名后,用同样的HASH算法对原报文计算出报文摘要值,然后与用发送者的公开密钥对数字签名进行解密(原先已经把签名加密了,再解密就能还原)得到的报文摘要值相比较。如相等则说明报文确实来自所称的发送者。
(由于只有拥有私钥的签名者能通过“解密”摘要生成签名,因此具有安全和不可抵赖性。)
那为什么是对报文摘要进行加密,而不是对原报文进行加密呢?这是因为RSA加解密非常耗时,被加密的报文越大,耗得时间越多,因此聪明的人类对其摘要进行加密,(因为报文摘要是要比原报文小得多),仍然能够起到同样的作用。这就是为什么多了个报文摘要。

7分类

基于数字证书的应用角度分类,数字证书可以分为以下几种:

服务器证书

服务器证书被安装于服务器设备上,用来证明服务器的身份和进行通信加密。服务器证书可以用来防止欺诈钓鱼站点
在服务器上安装服务器证书后,客户端浏览器可以与服务器证书建立SSL连接,在SSL连接上传输的任何数据都会被加密。同时,浏览器会自动验证服务器证书是否有效,验证所访问的站点是否是假冒站点,服务器证书保护的站点多被用来进行密码登录、订单处理、网上银行交易等。全球知名的服务器证书品牌有GlobalSignVerisignThawteGeotrust等。
SSL证书主要用于服务器(应用)的数据传输链路加密和身份认证,绑定网站域名,不同的产品对于不同价值的数据和要求不同的身份认证。
最新的高端SSL证书产品是扩展验证(EV)SSL证书。在IE7.0、FireFox3.0、Opera 9.5等新一代高安全浏览器下,使用扩展验证VeriSign(EV)SSL证书的网站的浏览器地址栏会自动呈现绿色,从而清晰地告诉用户正在访问的网站是经过严格认证的。
SSL证书还有企业型SSL证书(OVSSL) 及域名型证书(DVSSL)。

电子邮件证书

电子邮件证书可以用来证明电子邮件发件人的真实性。它并不证明数字证书上面CN一项所标识的证书所有者姓名的真实性,它只证明邮件地址的真实性。
收到具有有效电子签名的电子邮件,我们除了能相信邮件确实由指定邮箱发出外,还可以确信该邮件从被发出后没有被篡改过。
另外,使用接收的邮件证书,我们还可以向接收方发送加密邮件。该加密邮件可以在非安全网络传输,只有接收方的持有者才可能打开该邮件。

个人证书

客户端证书主要被用来进行身份验证和电子签名。
安全的客户端证书被存储于专用的usbkey中。存储于key中的证书不能被导出或复制,且key使用时需要输入key的保护密码。使用该证书需要物理上获得其存储介质usbkey,且需要知道key的保护密码,这也被称为双因子认证。这种认证手段是目前在internet最安全的身份认证手段之一。key的种类有多种,指纹识别、第三键确认,语音报读,以及带显示屏的专用usbkey和普通usbkey等。
数字证书在广义上可分为:个人数字证书、单位数字证书、单位员工数字证书、服务器证书、VPN证书、WAP证书、代码签名证书和表单签名证书。

8证书格式

数字证书的格式普遍采用的是X.509V3国际标准,一个标准的X.509数字证书包含以下一些内容:
证书的版本信息;
证书的序列号,每个证书都有一个唯一的证书序列号;
证书所使用的签名算法;
证书的发行机构名称,命名规则一般采用X.500格式;
证书的有效期,通用的证书一般采用UTC时间格式,它的计时范围为1950-2049;
证书所有人的名称,命名规则一般采用X.500格式;
证书所有人的公开密钥
证书发行者对证书的签名。
依据《电子认证服务管理办法》《中华人民共和国电子签名法》,目前国内有30家机构获得相关资质,具体资质可以查询工业信息化部网站。
数字证书文件格式(cer和pfx)的区别:
作为文件形式存在的证书一般有这几种格式:
1.带有私钥的证书由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式,以pfx作为证书文件后缀名。
2.二进制编码的证书 证书中没有私钥,DER 编码二进制格式的证书文件,以cer作为证书文件后缀名。
3.Base64编码的证书证书中没有私钥,BASE64 编码格式的证书文件,也是以cer作为证书文件后缀名。
由定义可以看出,只有pfx格式的数字证书是包含有私钥的,cer格式的数字证书里面只有公钥没有私钥。
在pfx证书的导入过程中有一项是“标志此密钥是可导出的。这将您在稍候备份或传输密钥”。一般是不选中的,如果选中,别人就有机会备份你的密钥了。如果是不选中,其实密钥也导入了,只是不能再次被导出。这就保证了密钥的安全。
如果导入过程中没有选中这一项,做证书备份时“导出私钥”这一项是灰色的,不能选。只能导出cer格式的公钥。如果导入时选中该项,则在导出时“导出私钥”这一项就是可选的。
如果要导出私钥(pfx),是需要输入密码的,这个密码就是对私钥再次加密,这样就保证了私钥的安全,别人即使拿到了你的证书备份(pfx),不知道加密私钥的密码,也是无法导入证书的。相反,如果只是导入导出cer格式的证书,是不会提示你输入密码的。因为公钥一般来说是对外公开的,不用加密。

9证书申请

一般来讲,用户要携带有关证件到各地的证书受理点,或者直接到证书发放机构即CA中心填写申请表并进行身份审核,审核通过后交纳一定费用就可以得到装有证书的相关介质(磁盘或Key)和一个写有密码口令的密码信封。
域名型的证书申请的时候,无须递交书面审查资料,仅需进行域名有效性验证,网上申请。而企业型证书需要进行严格的网站所有权的真实身份验证,证书标示企业组织机构详情,强化信任度。增强型证书除了进行严格的网站所有权的真实身份验证之外,还加入第三方验证,证书标示增强组织机构详情,强化信任度。

10使用方法

用户在进行需要使用证书的网上操作时,必须准备好装有证书的存储介质。如果用户是在自己的计算机上进行操作,操作前必须先安装CA根证书。一般所访问的系统如果需要使用数字证书会自动弹出提示框要求安装根证书,用户直接选择确认即可;当然也可以直接登陆CA中心的网站,下载安装根证书。操作时,一般系统会自动提示用户出示数字证书或者插入证书介质(IC卡或Key),用户插入证书介质后系统将要求用户输入密码口令,此时用户需要输入申请证书时获得的密码信封中的密码,密码验证正确后系统将自动调用数字证书进行相关操作。使用后,用户应记住取出证书介质,并妥善保管。当然,根据不同系统数字证书会有不同的使用方式,但系统一般会有明确提示,用户使用起来都较为方便。

11应用

随着Internet的普及、各种电子商务活动和电子政务活动的飞速发展,数字证书的应用是广泛的,目前主要包括:发送安全电子邮件、访问安全站点、网上招标投标、网上签约、网上订购、安全网上公文传送、网上缴费、网上缴税、网上炒股、网上购物和网上报关等。其中包括大家最为熟悉的用于网上银行的USBkey和部分使用数字证书的VIEID即网络身份证。

12网络身份证

全称:(Virtual identity electronic identification)虚拟身份电子标识。
网络身份证(VIEID)是互联网络信息世界中标识用户身份的工具,用于在网络通讯中识别通讯各方的身份及表明我们的身份或某种资格。VIEID并不是全部基于数字证书的。

背景

在互联网时代,人们以网络为平台构建了一个繁荣的互联网社会。在这个特殊的社会里,巨量基于互联网的各种应用服务和人数众多的网民构成了互联网的根本,但也因此使得互联网杂乱不堪和危险。在这种以网络代码基础的交流方式里,人们以虚拟的身份出现,正是这种交流方式给于了不法份子以可乘之机进而出现了网络盗窃、诈骗等违法犯罪活动。基于此,互联网环境迫切需要变革,而网络实名制和网络身份证(VIEID)正是良方。在这方面,互联网的发源地美国已先行先试。2011年1月17日奥巴马政府责成美国商务部,就如何才能妥善地建立一套“网络身份证”制度尽快出一个解决方案。美国商务部长骆家辉和白宫网络安全协调员施密特7日在斯坦福经济政策研究院出席公开活动时透露,总统奥巴马将于未来数月公开一份名为《身份认证国策》的草案。其它互联网用户大国的相关计划亦已提上日程或正在实施当中。

作用

网络身份证(VIEID)的出现将使互联网变的更加简便、高效、安全与可信。在不久的未来,每一位互联网的使用者都将拥有一个网络身份证。这将使你使用各种互联网服务时更加方便,不需要再填写烦琐的注册信息,只需要输入你的网络身份证号和管理密码即可轻松完成,且不需要再记住其它的各种烦琐的账号和密码。在你的网络身份证管理中心可以管理你在互联网所使用的服务亦可查看你在互联网留下的所有足迹。比如你注册使用了facebook、fasdl、QQ、人人网、开心网等,在你的网络身份证管理中心就能直接使用这些服务而不需要再输入账号密码。在你不想使用某一项服务时,直接在网络身份证管理中心注销既可。有了VIEID,互联网的每一位用户都可以相互信任彼此的身份,同时,严格且完善的隐私管理机制也使得用户的个人信息免遭泄露。

5月 292015
 

PKCS #8 使用 ASN.1 的 DER 编码规则。

openssl.exe/openssl 默认生成 PEM 格式的 RSA 密钥对(经过base64编码)。


1、生成pem格式私钥,  执行命令openssl genrsa -out rsa_private_key.pem 1024

rsa_private_key.pem内容类似下面:

—–BEGIN RSA PRIVATE KEY—–
MIICXQIBAAKBgQDfUZsrPhdVmGT5OcCKlUdQcaCeZtH7HyFEgAyuerfK3B/eOAv6
mBtf2lcZ5vCqrsdEKdT96rd3N2q9Cv1R0OryJMtZ9gwEhnRxSsyEd1/xSl4EOfmV
hqn8RGjBHbSpQuiCXwVicIzKIdmN4WM0dH1M/ZweLeVR75jI7DuQtpdTowIDAQAB
AoGBAJzn+q1sZ/rFI5UU5dq5Pi0gWSlStxDJc5dsnPxuzvoipeV93bTJ8NntUCur
3sceHHYhKjzqENQbxMxkj05QCvKdqZBjAImJvaObto4JeJPa7FEzIYiVqMfPoSOa
qIEp9LkJeGRy0x2stYvpxIfWwiOC/FKCw4bzK8tkfxb1q7+5AkEA80/Hy2MHWxRL
zhnEhIb+6TRWj5gaKZVbJn90t4AllC9tKrNDTBY0BKJwbsJvs+lbjtgMsvBL4+r+
0mhL4RWn/wJBAOr2644nbS5y8mSbnMX2PmXaphz7I1DuU7ynLuEU17qh08ucLkHy
p+Ik3A9wFfySLHUkwzZw8RUQlbkNpDhmtF0CQHFGUD7pILCPd2dBadNFQgHyIuaB
KpT3etMmfYE8wMIHfmxlvsv6fkc2FOAL15NL7htHjEn2Q26dpfrxIXpt6aMCQG5L
so9sWogvVTF9Cr6ytN/DH68DBLT86znnkM3/prTpOi6eBejXK4+wlcx5ZRjG1S+4
LhrkMYcd3eqcSLZhH9ECQQCxZc/g+hyzCPdx6BGv/0DJ3MQBC3MAJUcbyers4KHD
//O0hssHqy5vuRQ9wrQeXv0wF0HNkh6VioEUkCPGS4pg
—–END RSA PRIVATE KEY—–


2、生成公钥,执行命令openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

rsa_public_key.pem内容类似下面

—–BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfUZsrPhdVmGT5OcCKlUdQcaCe
ZtH7HyFEgAyuerfK3B/eOAv6mBtf2lcZ5vCqrsdEKdT96rd3N2q9Cv1R0OryJMtZ
9gwEhnRxSsyEd1/xSl4EOfmVhqn8RGjBHbSpQuiCXwVicIzKIdmN4WM0dH1M/Zwe
LeVR75jI7DuQtpdTowIDAQAB
—–END PUBLIC KEY—–


有的程序需要PKCS8格式到私钥(PHP服务端语言读取私钥不需要PKCS8转换),使用下面命令:

3、将RSA私钥转换成PKCS8格式,命令执行openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

输出内容类似下面:

—–BEGIN PRIVATE KEY—–
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN9Rmys+F1WYZPk5
wIqVR1BxoJ5m0fsfIUSADK56t8rcH944C/qYG1/aVxnm8Kqux0Qp1P3qt3c3ar0K
/VHQ6vIky1n2DASGdHFKzIR3X/FKXgQ5+ZWGqfxEaMEdtKlC6IJfBWJwjMoh2Y3h
YzR0fUz9nB4t5VHvmMjsO5C2l1OjAgMBAAECgYEAnOf6rWxn+sUjlRTl2rk+LSBZ
KVK3EMlzl2yc/G7O+iKl5X3dtMnw2e1QK6vexx4cdiEqPOoQ1BvEzGSPTlAK8p2p
kGMAiYm9o5u2jgl4k9rsUTMhiJWox8+hI5qogSn0uQl4ZHLTHay1i+nEh9bCI4L8
UoLDhvMry2R/FvWrv7kCQQDzT8fLYwdbFEvOGcSEhv7pNFaPmBoplVsmf3S3gCWU
L20qs0NMFjQEonBuwm+z6VuO2Ayy8Evj6v7SaEvhFaf/AkEA6vbrjidtLnLyZJuc
xfY+ZdqmHPsjUO5TvKcu4RTXuqHTy5wuQfKn4iTcD3AV/JIsdSTDNnDxFRCVuQ2k
OGa0XQJAcUZQPukgsI93Z0Fp00VCAfIi5oEqlPd60yZ9gTzAwgd+bGW+y/p+RzYU
4AvXk0vuG0eMSfZDbp2l+vEhem3powJAbkuyj2xaiC9VMX0KvrK038MfrwMEtPzr
OeeQzf+mtOk6Lp4F6Ncrj7CVzHllGMbVL7guGuQxhx3d6pxItmEf0QJBALFlz+D6
HLMI93HoEa//QMncxAELcwAlRxvJ6uzgocP/87SGywerLm+5FD3CtB5e/TAXQc2S
HpWKgRSQI8ZLimA=
—–END PRIVATE KEY—–

把上面内容复制到一个新文件中(包含BEGIN PRIVATE KEYEND PRIVATE KEY行-),任意起名,就得到了一个PKCS8格式到RSA私钥。

参考资料:

用途:

pkcs8格式的私钥转换工具。它处理在PKCS#8格式中的私钥文件。它可以用多样的PKCS#5 (v1.5 and v2.0)PKCS#12算法来处理没有解密的PKCS#8 PrivateKeyInfo格式和EncryptedPrivateKeyInfo格式。

用法:

  1. openssl pkcs8 [-inform PEM|DER] [-outform PEM|DER] [-in filename] [-passin arg] [-out filename]   
  2. [-passout arg] [-topk8] [-noiter] [-nocrypt] [-nooct] [-embed] [-nsdb] [-v2 alg] [-v1 alg] [-engine id]  

选项说明:

-inform PEM|DER::输入文件格式,DER或者PEM格式。DER格式采用ASN1DER标准格式。一般用的多的都是PEM格式,就是base64编码格式。

-outform DER|PEM:输出文件格式,DER或者PEM格式。

-in filename:输入的密钥文件,默认为标准输入。如果密钥被加密,会提示输入一个密钥口令。

-passin arg:输入文件口令保护来源。

-out filename:输出文件,默认为标准输出。如果任何加密操作已经执行,会提示输入一个密钥值。输出的文件名字不能和输入的文件名一样。

-passout arg:输出文件口令保护来源。

-topk8:通常的是输入一个pkcs8文件和传统的格式私钥文件将会被写出。设置了此选项后,位置转换过来:输入一个传统格式的私钥文件,输出一个PKCS#8格式的文件。

-noiterMAC保护计算次数为1

-nocryptPKCS#8密钥产生或输入一般用一个适当地密钥来加密PKCS#8 EncryptedPrivateKeyInfo结构。设置了此选项后,一个不加密的PrivateKeyInfo结构将会被输出。这个选项一直不加密私钥文件,在绝对必要的时候才能够使用。某些软件例如一些JAVA代码签名软件使用不加密的私钥文件。

-nooct这个选项产生的RSA私钥文件是一个坏的格式,一些软件将会使用。特别的是,私钥文件必须附上一个八位组字符串,但是一些软件仅仅包含本身的结构体没有使八位组字符串所环绕。不采用八位组表示私钥。

-embed:这个选项产生的RSA私钥文件是一个坏的格式。在私钥结构体中采用嵌入式DSA参数格式。在这个表单中,八位组字符串包含了ASN1 SEQUENCE中的两种结构:一个SEQUENCE包含了密钥参数,一个ASN1 INTEGER包含私钥值。

-nsdb:这个选项产生的RSA私钥文件是一个坏的格式并兼容了Netscape私钥文件数据库。采用NetscapeDBDSA格式。

v2 alg:采用PKCS#5 v2.0,并指定加密算法,默认的是PKCS#8私钥文件被叫做B<pbeWithMD5AndDES-CBC>(该算法用56字节的DES加密但是在PKCS#5 v1.5中有更加强壮的加密算法)的加密算法用口令进行加密。用B<-v2>选项,PKCS#5 v2.0相关的算法将会被使用,可以是des3168字节)和rc2128字节),推荐des3

-v1 alg:采用PKCS#5 v1.5pkcs12,并指定加密算法。可采用的算法见下面。

 -engine id:指定硬件引擎。

注意:

加密了的PEM编码PKCS#8文件表单用下面的头部和尾部:

—–BEGIN ENCRYPTED PRIVATE KEY—–

 —–END ENCRYPTED PRIVATE KEY—–

未加密的表单用:

—–BEGIN PRIVATE KEY—–

 —–END PRIVATE KEY—–

跟传统的SSLeay算法相比,用PKCS#5 v2.0系列的算法加密私钥,有更高的安全性以及迭代次数。于是附加的安全性是经过深思熟虑的。

默认的加密算法仅仅是56字节的,是因为它是PKCS#8所支持的最好的方法。

有一些软件使用PKCS#12基于密钥的加密算法来加密PKCS#8格式的私钥:它们会自动的处理但是没有选项来操作。

PKCS#8格式中,有可能的是输出DER编码格式的经过加密的私钥文件,是因为加密的详细说明包含在DER等级中,相反的是传统的格式包含在PEM邓丽中。

PKCS#5 v1.5 PKCS#12 算法:

各种各样的算法可以被选项-v1所使用。包含PKCS#5 v1.5 PKCS#12 算法。详细描述如下:

B<PBE-MD2-DES PBE-MD5-DES>:这两个算法包含在PKCS#5 v1.5中。它们仅仅提供56字节的保护,加密算法用DES

B<PBE-SHA1-RC2-64 PBE-MD2-RC2-64 PBE-MD5-RC2-64 PBE-SHA1-DES>:它们在传统的PKCS#5 v1.5中没有被提到,但是它们用同样地密钥引出算法,被一些软件所支持。在PKCS#5 v2.0中所提到。它们使用64字节的RC2以及56字节的DES

B<PBE-SHA1-RC4-128 PBE-SHA1-RC4-40 PBE-SHA1-3DES PBE-SHA1-2DES PBE-SHA1-RC2-128 PBE-SHA1-RC2-40>:它们是PKCS#12基于密钥的加密算法,它们允许使用高强度的加密算法,例如3des128位的RC2

实例:

3des算法将传统的私钥文件转换为PKCS#5 v2.0

  1. openssl pkcs8 -in key.pem -topk8 -v2 des3 -out enckey.pem  


PKCS#5 1.5兼容的DES算法将私钥文件转换为pkcs8文件:

[html] view plaincopy

  1. openssl pkcs8 -in ocspserverkey.pem -topk8 -out ocspkcs8key.pem  


PKCS#12兼容的3DES算法将私钥文件转换为pkcs8文件:

[html] view plaincopy

  1. openssl pkcs8 -in key.pem -topk8 -out enckey.pem -v1 PBE-SHA1-3DES  


读取一个DER格式加密了的PKCS#8格式的私钥:

  1. openssl pkcs8 -inform DER -nocrypt -in key.der -out key.pem  


转换一个PKCS#8格式的私钥到传统的私钥:

  1. openssl pkcs8 -in pk8.pem -out key.pem  


pkcs8中的私钥以明文存放:

[html] view plaincopy

  1. openssl pkcs8 -in ocspserverkey.pem -topk8  -nocrypt -out ocspkcs8key.pem  


标准:

PKCS#5 v2.0的测试向量的实现是以通告的形式用高强度的迭代次数算法3DESDESRC2来加密的。很多人要确认能够解密产生的私钥。

PKCS#8格式的DSA私钥文件没有备注文件中的:在PKCS#11 v2.01中的11.9节被隐藏了的。OpenSSL的默认DSA PKCS#8私钥格式隐藏在这个标准中。

BUGs

必须有一个选项打印使用的加密算法的其他详细细节,例如迭代次数。

PKCS#83DESPKCS#5 v2.0必须是默认的私钥文件:目前为了命令的兼容性。