《JavaTM程序设计语言基 础》第 2 部分
第 3 课:加密

[<<后退] [目录] [下一课>>]

许多人对自己的信用卡密码都采取了保护措施,这样做就对了。任何一个带有 私有信息的被盗信用卡号码都可能被盗窃者用来给失窃者的生活造成严重伤害。 在通过网络发送时,为信用卡和其它私有信息保密的方法之一是对其进行加密。

加密是一种在纯文本中加入一个密钥而把纯文本转换成无法理解的文本(加密 文本)的过程。只有利用带有把加密文本转换回最初文本的密钥的程序,才能对 被保护的信息进行解密。

本课利用 第 2 部分、第 2 课:再谈用户界面一节中 的示例程序来加密在网络中传输前的信用卡号,并在网络的另一端进行解密。


注意:由于加密软件不能出口到美国和加拿大境外,所以本课 中的示例程序采用的是伪代码而不是源代码。

示例程序的说明

为了在网络中安全地发送信用卡号,示例程序在获取到终端用户输入的信用卡 号纯文本信息后,把该信息传递给其内部的 encrypt 方法。

encrypt 方法创建一个密码会话密钥并使用这个带有密码的会话密 钥对信用卡号进行加密。

会话密钥在每次按下 Purchase 按钮时都会更新。改变会话密 钥可以防止未获授权的程序窃取密钥并用它解密其它信用卡号。

信用卡号采用同一个会话密钥实施加密和解密。这种加密技术叫做对称密钥加 密,在我们所举的示例中,要求把会话密钥和加密后的信用卡号通过网络发送给 接收程序。由于会话密钥是通过网络发送的,所以也应该采取防止未经授权者对 其解密的措施。

若要保护会话密钥,就需要利用接收方的公共密钥进行加密或保护。这样即使 未获得授权的程序截取了经过加密的会话密钥和信用卡号,也还必须用目的接收 者的私有密码来还原会话密钥才能解密带有会话密钥的信用卡号。

用公共密钥加密的任何内容都只能用最初加密该内容的公共密钥所对应的私有 密钥解密。这种加密技术被称做非对称加密。在示例程序中,所创建的公共密钥 可为请求它的客户程序所用,而私有密钥则是保密的且只供已获授权的指定客户 使用。

如图所示,本示例程序利用一个单独的程序创建一组公共/私有密钥对。公共 密钥存放在一个文件中,而私有密钥则保存在另外一个文件中。存放有私有密钥的 文件必须保存在非常安全的地方。许多公司都把私有密钥存放在磁带或磁盘等外 部存储介质上,以防止未授权人员或程序侵入系统获取私有密钥。

服务器程序从公共机密文件中调入公共密钥,并提供给订货客户加密会话密钥。 订单处理客户机得到加密后的会话密钥和信用卡号后,将调入私有密钥,使用私 有密钥解密会话密钥,并使用会话密钥解密信用卡号。

运行示例程序

如果您在美国或加拿大境内,您就可以从 Products & APIs 网页上下载 javax.crypto 程序包。该程序 包包含文档和一个带有加密 API 和服务提供程序的 JavaTM JAR文件。加密服务提供程序是具体实现加密算法的一个或一组程序包。

把 JAR 文件复制到安装Java 2 软件开发工具包标准版的 jdk1.2/jre/lib/ext 目录下,或复制到安装Java 运行时环境(JRE) 1.2版本的 jre1.2/lib/security 目录下。

务必确保 jdk1.2/jre/lib/security/java.securityjre1.2/lib/security/java.security 文件中有以下输入项。

#
security.provider.1=sun.security.provider.Sun
security.provider.2=com.sun.crypto.provider.SunJCE

此外,还需要安装带有 Rivest、Shamir 和 Adleman(RSA)非对称加密算法 之类的非对称算法的程序包。

为公共和私有密钥加密创建非对称密码时,就需要使用非对称算法。把非对称 算法程序包添加到 jdk1.2/jre/lib/security/java.securityjre1.2/lib/security/java.security 中充当 security.provider.3=,然后把它存放到包含其它 JAR 文件的 jdk1.2/jre/lib/ext or jre1.2/lib/ext 目录下。

利用下载程序中的文档把伪代码转换成源代码。

编译并运行示例程序。

Pseudo Code

密码对象在加密和解密过程中使用。密码对象根据在用的加密类型采用特定的 加密算法创建。本例中,使用了两种加密算法:对称加密和非对称加密。

对称密钥加密采用数据加密标准(DES)等对称算法。非对称密钥加密采用 Rives、Shamic 和 Adleman(RSA)非对称加密算法等非对称算法。

javax.crypto 程序包为对称和非对称加密定义了框架结构,其 中可插入具体的加密实现方法。符合 JCE 1.2 标准的 SunJCE 提供者仅提供 DES 等对称加密算法的实现方法。对于 RSA 等非对称加密算法的实现方法,则需 要安装其他提供者提供的程序包。

伪代码程序给出了用两种对会话密钥进行非对称加密的方法。其中一种是利用 RSA 密钥来加密对称密钥。另一种则是采用另外的非对称算法来封存(加密)对 称密钥。封存(sealing)是最佳的方法,但是这种方法在您使用 RSA 密钥时却 会出现问题;这是因为 RSA 算法会把一个大小限制(见下文)强加到正在加密 的对象上,而封存则使对象对 RSA 加密而言显得过于庞大。

采用正确的对称或非对称算法创建密码后,就可以使用密钥对加密或解密过程 进行初始化。在对称加密时,所用的密钥是一个保密的密钥,而非对称加密时的 密钥则是公共密钥或私有密钥。

服务器

通过 Send 接口方法声明而由 RemoteServer 类 实现的方法完成对加密信用卡号和加密保密密钥的处理。该程序还定义了一个用 于在客户机请求时返回公共密钥的方法。在伪代码程序中,这就是服务器接口方 法和类需要声明及实现的:

  A method to get the public key
  A method to send the encryped credit card number
  A method to get the encrypted credit card number
  A method to send the encrypted symmetric key
  A method to get the encrypted symmetric key

创建公共密钥和私有密钥对

您需要有一个程序来创建一个公共/私有密钥对并把它们保存到单独的文件中。 公共密钥在客户方法调用获取公共密钥的方法时从其文件中读取。私有密钥则在 RMIClient2 需要使用它解密保密密钥时从其文件中读取。

  Generate public and private key pair
	using asymmetric algorithm
  Store private Key in very safe place
  Store public key in accessible place

封存对称密钥

对称密钥的封存包括创建一个使用非对称密码封存(加密)会话密钥的封存对 象。因为文本域中设定了大小限制,而封存过程会使会话密钥太大而不能与 RSA 算法一起使用,所以不能采用 RSA 非对称算法。

RMIClient1Sealed.java: RMIClient1.java 代码采用 encrypt 方法加密信用卡号、封存对称密钥并向服务器 发送加密信用卡号和已封存密钥。以下是完成这一系列操作的伪代码程序:

  private void encrypt(credit card number){
    Create cipher for symmetric key encryption (DES)
    Create a key generator
    Create a secret (session) key with key generator
    Initialize cipher for encryption with session key
    Encrypt credit card number with cipher
    Get public key from server
    Create cipher for asymmetric encryption 
                               (do not use RSA)
    Initialize cipher for encryption with public key
    Seal session key using asymmetric Cipher
    Send encrypted credit card number and sealed 
	session key to server
  }

RMIClient2Sealed.java: RMIClient2.java 采用一个 decrypt 方法开启对称密钥并解密信用卡号。以下是实现 这些操作的伪代码程序:

public byte[] decrypt(encrypted key,
                        encrypted credit card number){
  Get private key from file
  Create asymmetric cipher (do not use RSA)
  Initialize cipher for decryption with private key
  Unseal wrapped session key using asymmetric cipher
  Create symmetric cipher 
  Initialize cipher for decryption with session key
  Decrypt credit card number with symmetric cipher
}

利用 RSA 算法加密对称密钥

RSA 算法向正在被加密的对象设定大小限制。RSA 加密采用带 PKCS#1 程序块 2 类填充法的 PKCS#1 标准。PKCS RSA 加密填充方案需要 11 个工作备用字节。 因此,如果创建一个带有 512 位密钥大小的 RSA 密钥对,就不能使用这些密钥 加密超过 53(53=64-11)个字节的信息。

于是,如果您的会话密钥大小只有 8 个字节长,封存可以把它扩展到 3644 个 字节,这就是避开 RSA 算法的大小限制的方法。在封存过程中,首先串行化需要 封存的对象(本例中指会话密钥),然后对串行化的内容进行加密。串行化过程向 会话密钥附加更多的信息,如会话密钥的类、类签名和会话密钥所影响的对象。 附加的信息使会话密钥太长而不能用 RSA 密钥进行加密,进而导致 javax.crypto.IllegalBlockSizeException 运行时错误。

RMIClient1.java:RMIClient1.java 代码采用 encrypt 方法加密信用卡号、封存(加密)会话密钥并向 服务器发送加密后的信用卡号和封存后的会话密钥。以下是实现该目的的伪代码程 序:

private void encrypt(credit card number){
  Create cipher for symmetric key encryption (DES)
  Create a key generator
  Create a secret (session) key with key generator
  Initialize cipher for encryption with session key
  Encrypt credit card number with cipher
  Get public key from server
  Create cipher for asymmetric encryption (RSA)
  Initialize cipher for encryption with public key
  Encrypt session key
  Send encrypted credit card number and session 
                                      key to server
  }

RMIClient2.java:RMIClient2.java 代码采用 decrypt 方法开启(解密)对称密钥并解密信用卡号。 以下是实现该目的的伪代码程序:

  public String decrypt(encrypted key,
                        encrypted credit card number){
    Decrypt credit card number
    Get private key from file
    Create asymmetric cipher (RSA)
    Initialize cipher for decryption with private key
    Decrypt symmetric key
    Instantiate symmetric key
    Create symmetric cipher
    Initialize Cipher for decryption with session key
    Decrypt credit card number with symmetric Cipher
  }

更多信息

有关密钥加密的详细说明见 Security Dynamics 网站(有关 RSA 加密的部分),或者利用搜索引擎按搜索有关 RSA 加密、非对称密钥加密或对称密钥加密方面的信息。

[TOP]

 

常见问答
下载中心
产品简介
 
 
Solaris论坛
 
   
 
null