现在的位置: 首页 > 综合 > 正文

Linux下Java程序调用Openssl命令实现内存中加密数据

2014年02月01日 ⁄ 综合 ⁄ 共 2188字 ⁄ 字号 评论关闭

转载地址:http://blog.csdn.net/ligaoyang/article/details/6867356

问题:

看了一下openssl enc命令的帮助信息,发现他的【in】参数只能接收一个文件,对这个文件加密后,输出一个新的加密后的文件。并不接收字符串作为加密对象。

客户给出的方案是,在磁盘上建立一个文件,将动态的字符串写入文件中,然后调用openssl enc加密,再读取加密后的文件,将加密后的数据发送给另外一个系统。完成这个操作后,建立的文件以及openssl输出的文件就没有用了,还需要将这些垃圾文件删除。

虽可行,但是涉及到并发访问以及文件操作,会很麻烦。

解决方案:

几经辗转,终于被我找到一个雅一点的解决方案,不会涉及到并发访问,也没有文件操作。

概要:

这里首先对 openssl enc 的参数【in】和【out】做一下深入的了解。

【in】参数接收一个文件作为加密对象,其实他还可以从标准输入读取数据。而且缺省就是从标准输入读取数据。

【out】参数会输出一个加密后的文件,他也一样可以将加密数据输出到标准输出设备上,而且缺省就是标准输出。

注意:从标准输入读取数据,并非就是在【in】参数后面直接输入加密的字符串,有兴趣的童鞋可以试一下,如果在【in】参数后面直接输入字符串,系统会毫不犹豫的告诉你:“加密的字符串“: No such file or
directory

要实现从标准输入读取数据,需要使用管道命令 “|”。稍后会讲解。

OK,数据输入问题解决了。

因为不想涉及文件操作,所以我会将加密后的数据输出到标准输出上,然后从Java程序中捕获输出流,并读取加密数据。

下面就详细讲解实现过程

实现:

先对管道命令做个简单的介绍。基本格式是:command1| command2

简而言之,就是将命令【command1】的输出作为命令【command2】的输入。前提是【command2】必须可以接收标准输入。

第一步:Openssl命令的实现

[plain] view
plain
copy

  1. echo -E "{0}" | openssl aes-128-cbc -e -kfile {1} -base64  

1. {0}就是要加密的数据,因为是动态的,我会在命令执行前,将它替换为真实的数据。

2.命令【ehco】就是向标准输出设备输出引号中的内容。这里将使用管道命令”|“将【echo】命令的输出作为【openssl】命令的输入。

注意:参数【-E】的作用是将引号的内容原本输出,而不做转义处理。否则,如果加密数据中含有特殊字符,会导致命令执行失败。

3.命令中没有【out】参数,命令的执行结果会缺省的输出到标准输出上。

4.参数【-kfile】是加密口令,它也必须接收一个文件参数。但是openssl也提供了非文件口令的参数 :【-k ”加密口令“】。加密口令是固定的,所以这里使用【-kefile】的方式,也便于将来管理员修改加密口令。{1}也会在执行命令前,被替换为真实的口令文件名。这不是本文的重点,有所了解即可。

第二部:在Java程序中调用Shell命令

[java] view
plain
copy

  1. /** 
  2.  * 数据加密处理 
  3.  *  
  4.  * @param data 要加密的数据 
  5.  * @param commonKey 加密口令文件名 
  6.  * @return 加密数据 
  7.  */  
  8. public static final synchronized String encryption(String data, String commonKey){  
  9.     // 加密后的数据定义  
  10.     String encryptionData = "";   
  11.       
  12.     try {  
  13.         // 加密命令  
  14.         String encryption = "echo -E \"{0}\" | openssl aes-128-cbc -e -kfile {1} -base64";  
  15.           
  16.         // 替换命令中占位符  
  17.         encryption = MessageFormat.format(encryption, data, commonKey);  
  18.           
  19.         String[] sh = new String[]{"/bin/sh""-c", encryption};  
  20.           
  21.         // Execute Shell Command  
  22.         ProcessBuilder pb = new ProcessBuilder(sh);  
  23.           
  24.         Process p = pb.start();  
  25.           
  26.         encryptionData = getShellOut(p);  
  27.   
  28.     } catch (Exception e) {  
  29.         throw new EncryptionException(e);  
  30.     }  
  31.       
  32.     return encryptionData;  
  33. }  

第三部:在Java程序中捕获Shell命令的输出流,并读取加密数据

[java] view
plain
copy

  1. /** 

抱歉!评论已关闭.