 | 级别: 初级 Nik Kesic (nikk@us.ibm.com), 软件工程师, IBM
2006 年 5 月 11 日 如果您拥有重要的、敏感的或机密的数据,而且未授权的人可能访问到或查看到这些数据,那么就必须进行数据加密。IBM® UniData® and UniVerse® (U2) 的扩展的 BASIC API 可以使用多种可用的密码系统对数据执行对称加密。U2 加密函数的核心是 OpenSSL 库。本文将遍历涉及 C#、Java、U2 BASIC 和 OpenSSL shell 脚本的四个领域的加密,并帮助您了解产生的数据加密如何在这四者中相互转换。
概述
本文对四种编程技术进行讨论,来演示对数据字符串进行对称加密:
- OpenSSL DOS 脚本 0.9.7e 版本(2004 年 10 月 25 日)
- 利用了 Visual Studio .NET 2003 的 C# 程序
- 使用了 JDK/JRE 1.5.0_04 的 Java 程序
- 使用了 UDT 7.1 或 UV 10.1 的 U2 BASIC 程序
为简单起见,本文使用 Windows® XP Professional 操作系统环境来演示所有这些程序示例。任何示例都不使用 salt,但是可以轻松修改提供的示例。除 C# 以外所有示例均可移植到更流行的业务系统环境中。希望这两种技术可以满足您当前的需求,或者至少为您指引正确的方向。我还执行了基准测试,为每项技术确定时间以计算一项加密操作花费的时间。
考虑示例前,我们首先复习一些术语的定义。
术语定义
何为加密?
加密(Encryption) 是把可读数据转化为密码数据的方法。尽管从开放消息存在起就已经使用加密来保护通信了,但是只有需要保密的组织和个人才使用加密。
图 1. 数据加密块图
第二次世界大战期间,现代加密技术开始得到重视,并在有关 Enigma 密码机和纳瓦霍族“风语者”的电影中流行起来。提出以上两个示例的本质是,只有在掌握密码机的控制权和密码强度有保证的情况下 Enigma 才会具有良好表现。尽管 Enigma 密码具有密码学弱点,其实它只是诸多重要因素共同造成的结果,如操作员造成的错误、程序缺陷、缴获密码机或电报密码本就能让密码破译者读取消息。
另一方面,风语者讲的语言只有他们自己才能明白,这就保证了安全通信。
 | |
切记:注意您居住地的法律。本文档中的信息可能会与您所在国家的管理密码研究实践的法律相冲突。本文不会解决这些区域问题。
|
|
当今,通过公共领域可以获得越来越多的信息,因此要求使用强大的加密技术来保护广泛使用的系统,如 Internet 电子商务和数据库应用程序,在这些系统中,可以查看到明文形式的口令、信用卡号和社会保障号这类信息。就加密和解密操作对系统性能的影响来说,设计应用程序时了解密码学强度也很重要。
如果加密的密匙安全,使用的密码强度足够(用于加密数据的位数),那么加密的密码数据将不会轻易被偷听者读取。
何为编码?
编码(Encoding) 是使用无需保密的代码将某些数据转化为其他形式数据的方法。这种转化以这种方式进行 —— 通过解码可以重新转化为原来的形式。同加密数据相比,知道代码的人可以完全理解编码数据。本文中,编码和解码并非用于隐藏数据的原始内容,而是作为一种机制使用,轻松地把数据从 A 点传输到 B 点并回传。加密数据往往难以查看而且不易传输。在本文稍后的 “示例” 一节,加密数据使用 Base64 编码。在解密开始前,首先应该对编码加密数据进行 Base64 解码。
何为密码学?
密码学(cryptology) 一词来源于希腊语 kryptos 和 logos,前者表示 “隐藏的(hidden)”,后者表示 “词(word)”。它是一个处理秘密通信的科学分支,通过使用代码和密码将明文的消息呈现为一种不可理解形式,只有知道密码才可以读取。
何为密码系统?
密码系统(cipher 或 cypher) 是一种算法,用于使用一系列良好定义的步骤对消息中的单个字母或多个字母执行加密(相反,解密)。据说最简单的一组密码系统是 Julius Caesar 与他的将军通信时使用的密码,因此,这种类型的密码就命名为 Caesar 密码。Caesar 密码的原理是移动字母的位置。
以下是移动 3 个字母位置的 Caesar 密码示例:
图 2. 工作中的 Ceasar 密码
在当今的用法中,原始信息被认为是明文,而加密形式的信息被认为是密文。密文消息包含所有明文消息的信息,但是没有适当的机制对它进行解密,密文将不能被人或计算机读取。对于不想让其读取的人或计算机来说,此消息就像是随机的杂乱数据。
通常使用一段被称为密钥(key) 的辅助信息对密码进行参数化。加密过程随改变算法的详细操作的密钥而不同。没有适当的密钥,就无法使用密码进行加密或解密操作。在本文稍后 “示例” 一节,将使用 RC2 (对称密钥块密码,由 RSA Data Security Inc.开发,现在已广泛可用) 加密算法。
何为算法?
算法(Algorithms) 是对数据执行加密的数学过程。在算法的整个使用过程中,信息转化为无意义的密文并需要使用密钥把数据转化回原始形式。Blowfish、AES RC4、RC5 和 RC6 是加密算法的例子。
何为 salt?
种子值用于明文口令的加密,以扩展从给定明文产生的密文的可能数量。salt 值是保护加密口令免受词典攻击的保护措施。
何为密钥?
密钥(key) 是加密算法用来将明文加密为密文的一连串字符。密钥是加密算法的触发机制。所以必须对密钥保密。
何为 IV?
初始化向量(Initialization Vector,IV) 作为对第一块字节进行加密和解密的种子。它确保两个数据块不会产生相同的加密文本块。IV 的尺寸取决于所使用的加密算法和加密协议。它通常与块或加密密钥一样大。加密信息的接受方必须分辨 IV 以对它解密。
以下两个图展示了 KEY-ACTUAL(HEX VALUE) 和 IV(HEX VALUE) 之间的差异(图 3),以及 Pass-Phrase(ASCII) 和 Salt(HEX VALUE) 之间的差异(图 4)。
图 3. 实际的密钥与 IV
图 4. Pass-Phrase 和 Salt
保护数据
应通过合理的安全措施保护敏感数据免于遭受以下风险:丢失、未经授权的访问、破坏、使用、更改或数据的泄露。
此外,公司政策应该规定,开发的任何保护数据的应用程序,由于其本身的性质,也应该只基于须知的基础,向雇员提供对数据的访问。
进行基准测试了解加密的性能影响
数据加密具有其代价。有必要通过考虑以下事项来仔细衡量加密的影响:
-
性能:在已经显现重负的系统上开始某些保护数据的有益活动可能带来毁灭性的后果。
-
加密的强度:加密的强度越大,加密或解密花费的时间就越长。
-
加密的数据尺寸:加密的数据要比明文 大。在本文使用的示例中,原始数据尺寸是八个字符。加密后的数据增长为 24 个字符。
-
数据类型:因为可能不需要对所有数据加密,所以要仔细定义哪个数据属性需要加密。
-
实时加密/解密:在随需应变的实时世界,很多应用程序需要遍历公共领域。仔细规划资源将有助于以必需的开销准备一个应用程序环境,来应对添加的工作和增长的数据尺寸。
本文的所有示例都提供一个简单的计时器,测量对八个字符加密/解密需要多少额外时间。您还将注意到,Java 示例与 C# 的比较结果会大为不同。务必了解性能变慢的原因以及如何通过仔细编程来克服弱点。示例故意编码成用于展示性能差异,让您来提供解决方案。
技术介绍
四个领域
本文中考察的可用于加密的四种技术类型是:
一定要注意,所有四个代码示例实际上都是很片面的。假设工作示例的一个基集似乎比正确的编码策略更重要。开发真实应用程序时,应实现更好的错误检测和错误捕获。所有四个示例都使用以下值:
- KEY (mykey) = ABCDEFGHIJKLMNOP
- IV (iv) = ABCDEFGH
- Input Data (instr) = My data string
OpenSSL 脚本
OpenSSL 脚本是本文演示的第一个同时也是最简单的示例。U2 默认情况下是使用库的 OpenSSL 组构建的。同时还包括一个 openssl 可执行文件,这是脚本示例的基础。不使用脚本执行定时。
注意,U2 并不支持 openssl 命令用到的所有函数。了解更多信息,请访问 OpenSSL Web 站点(参见 参考资料)。本脚本示例中仅使用 enc 命令和一些选项。清单 1 描述了使用的选项:
清单 1. OpenSSL 命令参考
openssl command [ command_opts ] [ command_args ] Command
enc [ options ] - Encryption and Decryption with Ciphers
Discription
The symmetric cipher commands allow data to be encrypted or decrypted
using various block and stream ciphers using keys based on passwords
or that are explicitly provided. Base64 encoding or decoding can also be performed
either by itself or in addition to the encryption or decryption.
OPTIONS
-in filename
the input filename, standard input by default.
-out filename
the output filename, standard output by default.
-pass arg
the password source. For more information about the format of arg, see the
PASS PHRASE ARGUMENTS section in openssl(1).
-salt
use a salt in the key derivation routines. This option should ALWAYS be
used unless compatibility with previous versions of OpenSSL or SSLeay is
required. This option is only present on OpenSSL, Versions 0.9.5 or later.
-nosalt
do not use a salt in the key derivation routines. This is the default for
compatibility with previous versions of OpenSSL and SSLeay.
-e
encrypt the input data: this is the default.
-d
decrypt the input data.
-a
base64 process the data. This means that if encryption is taking place, the
data is base64 encoded after encryption. If decryption is set, the
input data is base64 decoded before being decrypted.
-A
if the -a option is set, base64 process the data on one line.
-k password
the password to derive the key from. This is for compatibility with previous
versions of OpenSSL; superseded by the -pass argument.
-kfile filename
read the password to derive the key from the first line of filename. This is
for compatibility with previous versions of OpenSSL; superseded by the -pass
argument.
-S salt
the actual salt to use: this must be represented as a string comprised only
of hex digits.
-K key
the actual key to use: this must be represented as a string comprised only
of hex digits. If only the key is specified, the IV must additionally be specified
using the -iv option. When both a key and a password are specified, the key
given with the -K option will be used and the IV generated from the password
will be taken. It probably does not make much sense to specify both key and
password.
-iv IV
the actual IV to use: this must be represented as a string comprised only
of hex digits. When only the key is specified using the -K option, the IV
must explicitly be defined. When a password is being specified using one
of the other options, the IV is generated from this password.
-p
print out the key and IV used.
-P
print out the key and IV used, then immediately exit: don't do any encryption
or decryption.
-bufsize number
set the buffer size for I/O
-nopad
disable standard block padding
-debug
debug the BIOs used for I/O.
|
DOS 脚本 QA1.BAT
以下所示的示例是 Windows XP 平台上的一个 DOS 脚本,它使用 OpenSSL 0.9.7.e 版本。
清单 2. 使用的选项
enc - Encryption and Decryption with Ciphers
-nosalt - Do not use a salt in the key derivation routines
-iv - 16 byte intermediate vector
-rc2 - Cipher name - 128 bit RC2 in CBC mode
-K - Actual 32 byte key in hexadecimal
\ - Line continuation character
-p - Display iv and key
-a - Base64 encode after encryption
- Base64 decode before decryption
-d - Decrypt the input data
-in - Input data file
-out - Encoded/encrypted data file
|
清单 3. QA1.bat 的内容
@echo off
echo Start of Encryption Test
openssl enc -nosalt -iv "4142434445464748" -rc2 -K \
"4142434445464748494A4B4C4D4E4F50" -p -a -in instring.asc -out outstring.res
echo Encrypted String: && type outstring.res
echo Decrypted String:
openssl enc -d -nosalt -iv "4142434445464748" -rc2 -K \
"4142434445464748494A4B4C4D4E4F50" -a -in outstring.res
echo.
|
清单 4. instring.asc 的内容
My data string **** NO linefeed at end
|
清单 5. 屏幕输出
Start of Encryption Test
key=4142434445464748494A4B4C4D4E4F50
iv =4142434445464748
Encrypted String:
AJnpU8i3/ckdMUqRBarZzw==
Decrypted String:
My data string
|
清单 6. outstring.res 的内容
注意事项
除非需要与以前版本的 OpenSSL 和 SSLeay 保持兼容,否则如果密钥派生自口令,就应该始终使用 -salt 选项。
没有 -salt 选项,就可能对口令执行有效的词典攻击或者攻击流密码加密数据。造成这种情况的原因是,没有 salt,相同口令则始终生成相同的加密密钥。使用 salt 时,加密数据的前八个字节保留给 salt —— 加密文件时随机生成这八个字节,解密时从加密文件读取这八个字节。
所有块密码通常使用 PKCS#5 填充,也称为标准块填充。这允许执行基本完整性和口令检查。然而,随机数据通过测试的几率大于二百五十六分之一,所以这不是理想的测试。
C# 程序 —— rc2crypt2
这是第二个加密示例,它是在 Microsoft Visual Studio .NET 2003 上使用 NET Environment 中的 C# 开发的。此程序使用与 OpenSSL 脚本示例中相同的密钥、iv 和数据。
清单 7. rc2crypt2.cs
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace nikcrypt2
{
class rc2crypt2
{
public static void Main()
{
// Input data string
String instr = "My data string";
String b64es;
String decstr;
byte[] fromEncrypt;
byte[] encrypted;
byte[] toEncrypt;
byte[] es;
// Create a new 128 bit key.
byte[] mykey = {0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,
0x4B,0x4C,0x4D,0x4E,0x4F,0x50};
// Create a new 64 bit initialization vector
byte[] iv = {0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48};
// or to be more readable
// byte[] mykey = Encoding.ASCII.GetBytes("ABCDEFGHIJKLMNOP");
// byte[] iv = Encoding.ASCII.GetBytes("ABCDEFGH");
try
{
// tick counter
long StartTickValue = Environment.TickCount;
Console.WriteLine("Start of Encryption Test\n");
//
ASCIIEncoding textConverter = new ASCIIEncoding();
// RC2 cryptology
RC2CryptoServiceProvider rc2Crypto = new RC2CryptoServiceProvider();
Console.WriteLine("Effective key size is {0} bits.",
rc2Crypto.EffectiveKeySize);
Console.WriteLine("Mode is {0}.", rc2Crypto.Mode);
// set cypher mode
// By default cypher mode CBC is selected ... change CBC to CFB, CTS, ECB,
// OFB as needed.
rc2Crypto.Mode = System.Security.Cryptography.CipherMode.CBC;
Console.WriteLine("");
// Display Key
String inKey = textConverter.GetString(mykey);
Console.WriteLine("Input Key: {0}", inKey);
// Display IV
String inIV = textConverter.GetString(iv);
Console.WriteLine("Input IV: {0}", inIV);
// Get an encryptor from key and IV.
ICryptoTransform encryptor = rc2Crypto.CreateEncryptor(mykey, iv);
// Encrypt the data.
MemoryStream rc2msEncrypt = new MemoryStream();
CryptoStream rc2csEncrypt = new CryptoStream(rc2msEncrypt, encryptor,
CryptoStreamMode.Write);
// Convert the data to a byte array.
toEncrypt = textConverter.GetBytes(instr);
//Write all data to the crypto stream and flush it.
rc2csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
rc2csEncrypt.FlushFinalBlock();
//Get encrypted array of bytes.
encrypted = rc2msEncrypt.ToArray();
// display encrypted string in base64
Console.WriteLine("");
//Convert encrypted to base64
b64es = Convert.ToBase64String(encrypted);
Console.WriteLine("Base64 encrypted output : " + (b64es));
// or
//Console.WriteLine("Base64 encrypted output :
// " + Convert.ToBase64String(encrypted));
// This is where the encrypted data would be transmitted to a recipient
// who already knows your secret key. Optionally, you ca
// also encrypt your secret key using a public key algorithm
// and pass it to the message recipient along with the RC2
// encrypted message. Base64 conversion of the encrypted string is useful
// for transmission using email and so on.
// Get a decryptor that uses the same key and IV as the encryptor.
ICryptoTransform decryptor = rc2Crypto.CreateDecryptor(mykey, iv);
// Convert base64 encrypted string to encrypted byte array
es = Convert.FromBase64String(b64es);
// Now decrypt the previously encrypted message using the decryptor
// obtained in the above step.
// or decrypt a encrypted base64 string
MemoryStream rc2msDecrypt = new MemoryStream(es);
CryptoStream rc2csDecrypt = new CryptoStream(rc2msDecrypt, decryptor,
CryptoStreamMode.Read);
fromEncrypt = new byte[es.Length];
//Read the data out of the crypto stream.
rc2csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
//Convert the byte array back into a string.
decstr = textConverter.GetString(fromEncrypt);
//Display the input string (instr) data and the decrypted data.
Console.WriteLine("");
Console.WriteLine("Input String: {0}", instr);
Console.WriteLine("Decrypted String: {0}", decstr);
Console.WriteLine("\n");
// tick counter in Milliseconds
long EndTickValue = Environment.TickCount;
long FinalTickValue = (EndTickValue - StartTickValue);
// Display elapsed time
Console.WriteLine("Elapsed Tick count {0}", + FinalTickValue + " ms");
}
catch (Exception e)
{
Console.WriteLine("Error : " + e);
}
}
}
}
|
清单 8. rc2crypt2.cs 的输出
Start of Encryption Test
Effective key size is 128 bits.
Mode is CBC.
Input Key: ABCDEFGHIJKLMNOP
Input IV: ABCDEFGH
Base64 encrypted output : AJnpU8i3/ckdMUqRBarZzw==
Input String: My data string
Decrypted String: My data string
Elapsed Tick count 16 ms
|
Java 程序 —— rc2crypt2
这是第三个加密示例,它是使用 SUN JVM 1.5.0_04 在 Windows XP 上用 Java 编写的。使用该版本 JVM 的原因是它包含 RC2 密码学方法。这个程序使用与 OpenSSL 脚本示例中相同的密钥、iv 和数据。
清单 9. rc2crypt2.java
package sample;
import javax.crypto.*;
import javax.crypto.spec.*;
import sun.misc.*;
/*
* @author nikk
*/
class rc2crypt2 {
public static void main(String args[]) {
String instr = "My data string";
String b64es;
String decstr;
byte[] encrypted;
byte[] toEncrypt;
byte[] fromEncrypt;
byte[] es;
// Create a new 128 bit key.
byte[] mykey = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50 };
// Create a new 64 bit initialization vector
byte[] iv = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 };
// or
// byte[] mykey = "ABCDEFGHIJKLMNOP".getBytes();
// byte[] iv = "ABCDEFGH".getBytes();
try {
// timer counter
long StartTime = System.currentTimeMillis();
System.out.println("Start of Encryption Test");
// encrypt
// Constructs a secret key from mykey using RC2 algorithm
SecretKeySpec key = new SecretKeySpec(mykey, "RC2");
// Constructs a parameter set for RC2 from the given effective key size
// (in bits) and IV.
RC2ParameterSpec rc2Spec = new RC2ParameterSpec(128, iv);
// Generates a Cipher object that implements the specified transformation.
// *** Very time expensive call ***
// for increase in speed, create object early
Cipher cipher = Cipher.getInstance("RC2/CBC/PKCS5Padding");
//
long CipherTime = System.currentTimeMillis();
long Test1Time = (CipherTime - StartTime);
System.out.println("Cost of cypher is " + Test1Time + " ms");
// Initializes this cipher with a key and a set of algorithm parameters.
// *** time expensive call ***
cipher.init(Cipher.ENCRYPT_MODE, key, rc2Spec, null);
long initTime = System.currentTimeMillis();
long Test2Time = (initTime - CipherTime);
System.out.println("Cost of init is " + Test2Time + " ms");
// Get encrypted array of bytes.
toEncrypt = instr.getBytes();
// Encrypts byte data in a single-part operation, or finishes a
// multiple-part operation
encrypted = cipher.doFinal(toEncrypt);
// Get the Key size in bits
int kbit = rc2Spec.getEffectiveKeyBits();
System.out.println("Effective key size is " + kbit + " bits.\n");
// get the cipher algorithm
String alg = cipher.getAlgorithm();
System.out.println("Algorithm " + alg);
// get the Key
System.out.println("Input Key : " + new String(key.getEncoded()));
// get the IV
System.out.println("Input IV : " + new String(cipher.getIV()) + "\n");
// Base 64 Encode the encrypted string
b64es = new BASE64Encoder().encodeBuffer(encrypted);
System.out.println("Base64 encrypted output : " + b64es);
// decrypt
// Convert base64 encrypted string to encrypted byte array
es = new BASE64Decoder().decodeBuffer(b64es);
// Initializes this cipher with a key and a set of algorithm parameters.
// ** dcipher.init(Cipher.DECRYPT_MODE, key, rc2Spec, null);
cipher.init(Cipher.DECRYPT_MODE, key, rc2Spec, null);
//decrypt byte array
// ** fromEncrypt = dcipher.doFinal(es);
fromEncrypt = cipher.doFinal(es);
// convert byte array into string
decstr = new String(fromEncrypt);
System.out.println("Input string : " + instr);
System.out.println("Output string : " + decstr);
// System.out.println("Output string : " + new String(fromEncrypt));
long EndTime = System.currentTimeMillis();
long TotalTime = (EndTime - StartTime);
System.out.println("Cost of encrypting 8 characters is " + TotalTime + " ms");
} catch (Exception e) {
System.out.println("Error : " + e);
}
}
}
|
清单 10. rc2crypt2.java 的输出
Start of Encryption Test
Cost of cypher is 407 ms
Cost of init is 62 ms
Effective key size is 128 bits.
Algorithm RC2/CBC/PKCS5Padding
Input Key : ABCDEFGHIJKLMNOP
Input IV : ABCDEFGH
Base64 encrypted output : AJnpU8i3/ckdMUqRBarZzw==
Input string : My data string
Output string : My data string
Cost of encrypting 8 characters is 469 ms
|
U2 BASIC
这是第四个加密示例,它使用 UniData 6.1.x、7.1.X 或 Universe 10.1.X 数据库。要注意的重要事项是,在撰写本文档时,只使用了 U2 BASIC 加密 API 的预发行版本。当前版本将不会产生本例中的输出,也不会具有本例中使用的语法。请查看最新的 U2 Readme,了解关于 eCase 8088 的信息,以确认可以产生正确的结果。BASIC 示例后有一个工作区 BASIC 示例,在将 8088 的问题实现到 U2 数据库中之前您一直可以使用它。
表 1. 加密语法
| 参数 | 描述 |
|---|
| algorithm | 一个包含密码名称的字符串。 | | action | 1:加密 |
| 2:加密后的 Base64 编码 |
| 3:解密 |
| 4:加密前的 Base64 解码 |
| 5:加密后转为一行 base64 |
| 6:对一行 base64 解码然后解密 | | data | 数据或包含待处理的数据的文件名称。 | | dataLoc | 1:字符串中的数据 |
| 2:文件中的数据 | | key | 实际的密钥(口令)或包含密钥的文件名称。 | | keyLoc | 1:数据中的密钥 |
| 2:文件中的密钥 | | keyAction | 1 KEY_ACTUAL 使用实际密钥(以前的行为,U2 自包含的) |
| 2 KEY_DERIVE_MD5 (以前的行为,U2 自包含的) |
| 3 KEY_ACTUAL_OPENSSL (新行为,U2-OpenSSL 兼容的) |
| 4 KEY_DERIVE_MD5 (新行为,如同以下各项,U2-OpenSSL 兼容的) |
| 5 KEY_DERIVE_SHA1(新的) |
| 6 KEY_DERIVE_MD2(新的) |
| 7 KEY_DERIVE_MDC2(新的) |
| 8 KEY_DERIVE_MD160(新的) |
| 9 KEY_DERIVE_SHA(新的) | | Salt | 包含 Salt 值的字符串。 | | IV | 包含 IV(十六进制表示)的字符串。 | | result | 结果缓冲区或存储结果的文件的名称。 | | resultLoc | 1 —— 字符串中的结果 |
| 2 —— 文件中的结果 |
表 2. 每个返回码的状态
| 返回码 | 状态 |
|---|
| 0 | 成功 | | 1 | 无效密码 | | 2 | 无效参数(位置/动作值溢出,等) | | 3 | 数据无法读取 | | 4 | 密钥无法派生 | | 5 | Base 64 编码/解码错误 | | 6 | 加密/解密错误 |
注意:Openssl enc 拥有一个 -md 选项,后面是 md5(默认)、md2、sha1 和 sha。OpenSSL 0.9.6e 不支持 -md 选项。因此对于 UV10.1来说,如果您使用 KEYACTION 3 - 5,将无法使用 OpenSSL 解密。
U2 BASIC 程序 —— RC2CRYPT
清单 11. RC2CRYPT
*
* written by Nik Kesic
*
A=protocolLogging("rc2crypt.log", "ON", "10") ; * Turn on logging
result=""
ALGORITHM="rc2-cbc" ; * 128 bit rc2 algorithm in CBC mode
MYKEY="4142434445464748494A4B4C4D4E4F50" ; * HEX - Actual Key
IV="4142434445464748" ; * HEX - Initialization Vector
INSTR="My data string" ; * Data String
DATALOC=1 ; * Data in String
KEYLOC=1 ; * Key in String
ACTION=2 ; * Base64 encode after encryption
KEYACTION=3 ; * KEY_ACTUAL_OPENSSL
SALT="" ; * SALT not used
RESULTLOC=1 ; * Result in String RESULT
PRINT "Start of Encryption Test"
CRT
PRINT "Effective key size is 128 bits."
PRINT "Algorithm ":ALGORITHM
PRINT "Input Key : ":MYKEY
PRINT "Input IV : ":IV
*
* Call to ENCRYPT function - 0 = good response
*
RETURN.CODE=ENCRYPT(ALGORITHM,ACTION,INSTR,DATALOC,MYKEY,KEYLOC,KEYACTION,SALT,IV,
RESULT,RESULTLOC)
IF RETURN.CODE <> 0 THEN
CRT "Error in Encrypt : "
STOP
END
CRT
PRINT "Base64 encrypted output : ":RESULT
*
ACTION="4" ; * Base64 decode before encryption
CRT "Input String : ":INSTR
*
* Call to DECRYPT function - 0 = good response\
*
RETURN.CODE=ENCRYPT(ALGORITHM,ACTION,RESULT,DATALOC,MYKEY,KEYLOC,KEYACTION,SALT,IV,
DECRESULT,RESULTLOC)
IF RETURN.CODE <> 0 THEN
CRT "Error in Decrypt : "
STOP
END
CRT "Decrypted String : ":DECRESULT ; * Output of decrypted string
FinalTime=SYSTEM(9) ; * Time program ran in milliseconds
PRINT "Cost of encrypting 8 characters is ":FinalTime:" ms"
A=protocolLogging("", "OFF", "") ; * Turn on logging
END
|
清单 12. U2 BASIC 示例的输出
Start of Encryption Test
Effective key size is 128 bits.
Algorithm rc2-cbc
Input Key : 4142434445464748494A4B4C4D4E4F50
Input IV : 4142434445464748
Base64 encrypted output : AJnpU8i3/ckdMUqRBarZzw==
Input String : My data string
Decrypted String : My data string
Cost of encrypting 8 characters is 10 ms
|
工作区 BASIC 示例
在 U2 技术问题 8088 解决之前,创建工作区示例来克服 OpenSSL 兼容性问题。要注意的一点是由 echo 命令引起的有意的换行符问题。在 UNIX 上,这将不是问题。但在 Windows 上,这将造成加密字符串看起来不同并增加一个换行符。甚至解密的字符串也有换行符。您必须始终考虑对数据产生影响的环境并决定如何对它处理。需要及时注意的另外一点是工作区的成本。
清单 13. BASIC /脚本示例
*
* written by Nik Kesic
* workaround for OPENSSL compatible encrypt until issue 8088 is resolved
*
IV="4142434445464748"
MYKEY="4142434445464748494A4B4C4D4E4F50"
ALGORITHM=" -rc2"
INSTR="My data string"
PRINT "Start of Encryption Test"
CRT
PRINT "Effective key size is 128 bits."
PRINT "Algorithm ":ALGORITHM
PRINT "Input Key : ":MYKEY
PRINT "Input IV : ":IV
*
comm="echo ":INSTR:"|openssl enc -nosalt -iv ":IV:ALGORITHM:"
-K ":MYKEY:" -a -out mydata.enc"
* PRINT comm
*
PCPERFORM "type mydata.enc" CAPTURING RESULT
CRT
PRINT "Base64 encrypted output : ":RESULT
PCPERFORM comm
*
* Universe
* EXECUTE comm
*
CRT "Input String : ":INSTR
dcomm="openssl enc -d -nosalt -iv ":IV:ALGORITHM:" -K ":MYKEY:" -a -in mydata.enc"
PCPERFORM dcomm CAPTURING DECRESULT
CRT "Decrypted String : ":DECRESULT
FinalTime=SYSTEM(9) ; * Time program ran in milli seconds
PRINT "Cost of encrypting 8 characters is ":FinalTime:" ms"
END
|
清单 14. 工作区的输出
Start of Encryption Test
Effective key size is 128 bits.
Algorithm -rc2
Input Key : 4142434445464748494A4B4C4D4E4F50
Input IV : 4142434445464748
Base64 encrypted output : AJnpU8i3/cml4YH2PsT2k4tspzJ5i9hC
Input String : My data string
Decrypted String : My data string
Cost of encrypting 8 characters is 26 ms
|
U2 数据加密的未来怎样?
题为 “U2's Susie Siegesmund on Security” 的新闻简报(Database Trends and Applications,2005 年 8 月)谈到了 U2 数据加密的未来:
 | |
IBM U2 Research and Development 小组在字段和/或记录级别考虑到性能、索引处理和加密密钥管理等因素,将完成灵活健壮的数据库级加密的架构设计。这个功能将在下一主要数据库版本(UniVerse 10.2 和 UniData 7.2 )中推出。安全性的关键组件是确保数据库及其应用程序是高度可用的且能在出现系统故障的时候轻松恢复。
|
|
完整文章的链接,参见 参考资料。
结束语
加密电子商务世界中的数据来保护数据所有者并非是不可调节的。全世界的执法部门和国家安全机构都担心加密通信的广泛使用将削弱他们打击犯罪或阻止犯罪活动和恐怖活动的能力。您的受众所在的地区可能强制要求采用所推荐的较小的加密算法。但是无论您的需求是什么,希望 U2 功能将为您提供一种机制,以充分保护通常是新闻标题的元素中的数据。
参考资料 学习
获得产品和技术
讨论
关于作者  | 
|  | Nik Kesic 在位于 Denver Colorado 的 IBM U2 Advanced Technical Support 小组工作。Nik 负责提供咨询、3 级支持和培训,并发表了关于使用 RedBack、套接字、XML、SOAP、SSL 和 Encryption 启用 Web 的文章。
|
对本文的评价
|  |