Saturday, September 09, 2006

How to use JCE - Part 2

Java加密扩展基础
http://www.phpwind.net/simple/index.php?t109465.html

对称密钥加密与解密
http://www.javatx.cn/clubPage.jsp?ccStyle=0&tID=798&ccID=16

Encrypt Sensitive Configuration Data with Java
http://www.devx.com/Java/10MinuteSolution/21385/1954?pf=true

Java Technology Forums - encrypt and decrypt sample code
http://forum.java.sun.com/thread.jspa?threadID=753209&tstart=135

探索 XML 加密,第 1 部分
http://www-128.ibm.com/developerworks/cn/xml/x-encrypt/index.html

Exploring XML Encryption, Part 2
http://www-128.ibm.com/developerworks/cn/xml/x-encrypt2/listing2.html

How to use JCE - Part 1

0. Introduction
JAVA的安全盾牌-JAVA安全技术 java几乎成为网络程序的标准语言,java给我们提供了先进的应用技术的同时,同时给我们提供了非常强大的安全技术。这些技术主要包括: 1 加密和解密技术; 2 JAVA源代码保护技术; 3 数据完整性保护技术(数字签名和消息摘要); 4 数字证书技术; 5 其它更高级的技术(包括Kerberos技术和JAVA GSS-API技术等等); Java加密扩展即Java Cryptography Extension,简称JCE。它是Sun的加密服务软件,包含了加密和密匙生成功能。JCE是JCA(Java Cryptography Architecture)的一种扩展。 JCE没有规定具体的加密算法,但提供了一个框架,加密算法的具体实现可以作为服务提供者加入。除了JCE框架之外,JCE软件包还包含了SunJCE服务提供者,其中包括许多有用的密码算法和数字签名算法,例如DES、RSA、DSA、SHA、MD5等。使用JCE进行加密解密非常方便,在后面我们将详细的讲述这一技术。 4 如何最大限度的保证应用的安全性系统被挂了我们可以重装系统,但是应用程序和服务的敏感数据和信息被改了或者被盗窃了那我们只有祈祷上帝,希望攻击者能够良心发现。不过千万不要沮丧,我们可以利用JAVA为我们提供的一些武器来增强我们的信心,利用这些东西至少可以挡住99%以上的攻击行为,使我们的损失最小化。(1) 使用JCE技术来加密敏感信息和保护敏感信息的数字摘要;(2) 使用JAVA Logging API建立日志和审核机制;(3) 使用JAAS进行用户身份认证和授权;(4) 利用数字签名技术保证数据的完整性;(5) 利用自定义的类加载器来加载加密后的JAVA类文件以抗击JAVA源代码分析和攻击;(6) 使用JCE来构筑安全通讯协议来保证数据传输的安全。 5使用JCE技术来加密敏感信息和保护敏感信息的数字摘要目前SUN公司的最新版本的JDK(JDK1.5)包含以下几种密码算法:(1)DES:DES(数据加密标准)是由 IBM 于上世纪 70 年代发明的,美国政府将其采纳为标准。它是一种 56 位分组密码。(2)TripleDES:该算法被用来解决使用 DES 技术的 56 位时密钥日益减弱的强度,其方法是:使用两个密钥对明文运行 DES 算法三次,从而得到 112 位有效密钥强度。TripleDES 有时称为 DESede(表示加密、解密和加密这三个阶段)。(3)AES:AES(高级加密标准)取代 DES 成为美国标准。它是由 Joan Daemen 和 Vincent Rijmen 发明的,也被称为 Rinjdael 算法。它是 128 位分组密码,密钥长度为 128 位、192 位或 256 位。(4)RC2、RC4、和 RC5:这些算法来自领先的加密安全性公司 RSA Security。(5)Blowfish:这种算法是由 Bruce Schneier 开发的,它是一种具有从 32 位到 448 位(都是 8 的整数倍)可变密钥长度的分组密码,被设计用于在软件中有效实现微处理器。(6)其它:包括RSA、MD5、SHA、DAS等。除此而外,由于JCE的开放性,JDK还支持第三方提供的密码算法。在系统中,我们首先应该搞清楚的问题是:(1)该对什么数据加密?(2)选择什么样的加密算法?(3)如何实现加密?回答这三个问题对于不同的系统有不同的说法,通常是根据应用来定的。打个比方,银行系统有两个字段:开户人帐号和开户人密码,那我们再权衡后会选择开户人密码。对于数据库系统而言,大规模加密会导致系统反映迟钝,严重影响效率。因此选择加密算法的时候必须考虑这点,对于数据加密我们用对称加密算法,对于对称加密算法密钥等信息我们可以使用公钥加密算法,对于流媒体我们可以采用流加密方法。下面我们来回答第三个问题,如何实现加密。通过JCE使用对称加密算法的过程一般是这样的: 1 引入JCE加密算法库; 2 将要加密的数据变成一个字节数组; 3 调用Cipher.getInstance建立一个Cipher实例; 4 选择加密模式,调用init方法传递密钥并初始化Cipher; 5 调用doFinal方法,传递要加密的字节数组进行加密; 6 将加密后的字节数组转变为普通的字符串类型。需要注意的是因为加密后的密文是未知的,其中可能出现对应于ASCII行尾符或者文件尾符的密文,因此一般在应用中我们采用BASE64编码进行处理。下面我们给出示范源代码(实际使用的代码比这个要复杂得多,并要使用BASE64编解码): /* writer:fleshwound
/
package myprojects.jce_smatrix; import javax.crypto.*; import java.security.*; import java.io.*; public class Jce_smatrix { public static String s="welcome to smatrix!";
public Jce_smatrix()
{
System.out.println("A JCE example begin:\n");
System.out.println("plain text is:"+s+"\n");
}
public static void main(String args[]) throws Exception
{
Jce_smatrix jceexa=new Jce_smatrix();

//初始化密钥
KeyGenerator kg=KeyGenerator.getInstance("Blowfish");
kg.init(128);
SecretKey key=kg.generateKey();
//加密
Cipher c=Cipher.getInstance("Blowfish/ECB/PKCS5padding");
c.init(Cipher.ENCRYPT_MODE,key);
byte[] content=s.getBytes("UTF8");
System.out.println("before ENCRYPT:");
for(int i=0;ihttp://www.smatrix.org/download/show.php?id=52

(reference: http://www.secwiki.com/wiki/index.php/æ•°æ®åŠ å¯†)
1. 配置jce开发环境
虽然JDK1.4将java安全包包含在核心库中,但如果不对jce进行配置,也没办法使用jce进行开发。
首先从sun网上下载jce1.2.2(我在网上看到的都是下载一个包,没用sun默认的),然后把解压得到的lib里面的所有jar文件拷到your_jdk\jre\lib\ext(your_jdk为你的jdk安装目录),编辑your_jdk\jre\lib\security\java.policy文件,在最后加上
grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" { permission java.io.FilePermission "file:${java.home}/lib/ext/sunjce_provider.jar", "read"; permission java.lang.RuntimePermission "getProtectionDomain"; permission java.security.SecurityPermission "putProviderProperty.SunJCE";};
给sunjce_provider授予访问权限 your_jdk\jre\lib\security\java.security里面配置了可选的provider类型,这里用默认配置就行了。(这里的provider也可由用户自己用别的厂商提供的包替换,我不是太清楚怎么作)。 由于我是用Jbuilder开发,必须加上对相关库的链接。所以就在Project下面的properties的library设置里面加上对jce1_2_2.jar、sunjce_provider.jar的引用,配置完毕之后,就可以进行JCE相关的程序编写了。
我用jce写了一个des加解密的小程序,不知道为什么,运行起来很慢。感觉是装载provider花时间。偶N不了解为什么sun会用provider这种安装组件的方式,很麻烦,也很没必要。我在eclipse下配置了半天都没弄好,郁闷死了
(Reference: http://www.cnblogs.com/lzcarl/archive/2005/07/27/201477.html)

2. 使用JCE进行DES加密

1、 引言
随着科技的日益发达,人们在对方便性要求逐渐提高的同时,对安全性的要求也日益提高。而使用加密的方法保护文件已成为计算机安全应用中重要的组成部分。DES加密方法作为一种世界标准的加密形式, 已经15 年历史了,虽然有些老, 可还算是比较可靠的算法,因此在加密应用中还是有一定的市场。
2、 DES算法简介
DES是一个分组加密算法,他以64位为分组对数据加密。同时DES也是一个对称算法:加密和解密用的是同一个密钥。它的密钥长度是56位(因为每8位的最后一位都用作奇偶校验),密钥可以是任意的56位的数,而且可以任意时候改变。其中有极少量的数被认为是弱密钥,但是很容易避开他们,所以保密性依赖于密匙。虽然DES算法实现起来比较简单,加解密速度也比较快,但是因为密钥过短,比较容易被破解,地位就逐渐被其他的加密算法取代。
3、 JCE简介及配置见http://www.cnblogs.com/archive/2005/07/27/201477.html
4、 DES加密程序
这个加密程序的密钥采取自动生成的方式,并把生成的密钥保存在文件中。这样只要拥有密钥文件就可以加解密从而避免了用户忘记密钥的问题,同时,由于每次加密使用的密钥都不相同,提高了安全性。
在设计这个加密程序的时候,考虑到以后这个程序的复用性,我将程序分为三个类:
BytesCipher:提供了对byte型数组进行加解密的功能,同时还可以生成DES密钥。
FileCipher:提供了对文件加解密的功能(先将文件转换成byte型数组),同时可以保存、读取密钥。
DESCipher:主程序类。我将整个程序设计成命令行形式,仿照dos命令,用户输入命令和相应的参数就可以执行程序,同时可以查看帮助。
在异常处理方面,我把程序执行过程中抛出的异常进行了二次处理,加上了自己赋予的异常信息,再发送到主函数中统一处理。
BytesCipher类代码:
import java.security.*;import javax.crypto.spec.*;import javax.crypto.*;public class BytesCipher { //默认使用des加密 private static String algorithm = "DES"; /** *//** * 使用JDK中的JCE生成密钥 */ public static byte[] generateKey() throws Exception { try { //生成一个可信任的随机数源 SecureRandom sr = new SecureRandom(); //为我们选择的DES算法生成一个KeyGenerator对象 KeyGenerator kg = KeyGenerator.getInstance(algorithm); kg.init(sr); //生成密钥 SecretKey key = kg.generateKey(); //返回密钥的二进制形式 return key.getEncoded(); } catch (Exception e) { throw new Exception("没有这种加密算法"); } } /** *//** * 根据密钥对明文进行加密,返回密文 */ public static byte[] encrypt(byte[] plaintext, byte[] key) throws Exception { try { //产生一个可信任的随机数源 SecureRandom sr = new SecureRandom(); //从原始密钥数据创建DESKeySpec对象 DESKeySpec dks = new DESKeySpec(key); //创建一个密钥工厂,然后用它把DESKeySpec转换成Secret Key对象 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm); SecretKey keySpec = keyFactory.generateSecret(dks); //Cipher对象实际完成加密操作 Cipher cipher = Cipher.getInstance(algorithm); //用密钥初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, keySpec, sr); //执行加密操作 byte[] cryptotext= cipher.doFinal(plaintext); return cryptotext; } catch (InvalidKeyException e) { throw new Exception("密钥非法"); } catch (NoSuchAlgorithmException e) { throw new Exception("没有这种加密算法"); } catch (BadPaddingException e) { throw new Exception("加密失败"); } } /** *//** * 根据密钥对密文进行加密,返回明文 */ public static byte[] decrypt(byte[] cryptotext, byte[] key) throws Exception {//上面与加密代码相同 cipher.init(Cipher.DECRYPT_MODE, keySpec, sr); //执行解密操作,下面与加密代码基本相同}

FileCipher类代码:

import java.io.*;import java.nio.*;import java.nio.channels.*;public class FileCipher { //明文 private static byte[] plaintext=null; //密文 private static byte[] cryptotext=null; //密钥 private static byte[] key; /** *//** * 从文件中读数据,返回byte型数组 */ private static byte[] readFile(String filename) throws Exception { try { File f = new File(filename); FileInputStream fs = new FileInputStream(f); FileChannel fc = fs.getChannel(); //只要文件大小不超过2G(int的范围)即可加密 int size = (int) fc.size(); //采用DirectBuffer的方式读文件数据,属于JDK1.4的API,处理大容量数据更快 ByteBuffer buffer=ByteBuffer.allocateDirect(size); //通过文件通道将文件内容读入ByteBuffer fc.read(buffer); //buffer操作完一次必须flip回到最初位置,才能再进行操作 buffer.flip(); byte[] byteArray=new byte[size]; //将缓冲区内容存入数组 buffer.get(byteArray); buffer.clear(); fc.close(); fs.close(); return byteArray; } catch (FileNotFoundException e) { throw new Exception("文件未找到"); } catch (IOException e) { throw new Exception("文件操作错误"); } } /** *//** * 将byte型数组内容写入文件 */ private static void writeFile(String filename,byte[] byteArray) throws Exception { //与读文件类似、省略 } /** *//** * 根据密钥对制定文件加密 */ public static void fileEncrypt(String filename,byte[] key) throws Exception { plaintext=readFile(filename); cryptotext=BytesCipher.encrypt(plaintext,key); writeFile(filename,cryptotext); } /** *//** * 根据密钥对指定文件解密 */ public static void fileDecrypt(String filename,byte[] key) throws Exception { cryptotext=readFile(filename); plaintext=BytesCipher.decrypt(cryptotext,key); writeFile(filename,plaintext); } /** *//** * 将得到的密钥保存到文件 */ public static void saveKey(String filename,byte[] key) throws Exception { writeFile(filename,key); } /** *//** * 从文件中读出密钥,返回byte数组形式 */ public static byte[] loadKey(String filename) throws Exception { key=readFile(filename); return key; }}
DESCipher类代码:

import java.io.*;public class DESCipher{ /** *//** * 打印命令的帮助信息 */ public static void printHelp() { //都是输出函数、省略 } public static void main(String[] args) { try{ //用户没有输入参数,则打印帮助 if(args.length==0) { printHelp(); return; } //用户输入参数个数不够,则提示用户,并打印帮助 if(args.length<3) key="BytesCipher.generateKey();" key2="FileCipher.loadKey(args[2]);" href="http://www.cnblogs.com/lzcarl/archive/2005/09/24/243471.html">http://www.cnblogs.com/lzcarl/archive/2005/09/24/243471.html)

Wednesday, June 28, 2006

Consultant opportuties in BJ

Position 1
IBM,China is seeking for a Senior Consultant for Global Technology Service
which is located in Peking.

As a Senior Consultant you will be engaged in business critical projects for
clients, who include many of the leading Chinese
banking,telecommunication,industrial,government customers. The responsibility
of a consultant may include engaging as a member of the project team, ability
to lead and manage others as appropriate, assist in the specification of
deliverables, provision of estimates and plans and progress reporting;
building and maintaining the personal expertise needed to provide expert
support to agreed service with the client and play an active part in the
internal structure of the practice.

Job Requirements (skills/experiences)
The consultants will also have experiences with analyzing complex IT and
business problems and designing IT strategy and solutions to help the
customers to solve the problems and support their business growth. The
consultants are also expected to lead a team to engage and deliver complex
solutions and perform delivery management for complex projects.

Requirments
Bachelor Degree in IT Management or Computer Science
MBA preferred

The annual package is around 600k


Position 2
BEA company
Field Engineers – Telecommunications Products
Location: Beijing, China
Requirment
7-10 years telecommunications industry experience
6 years experience as an systems engineer, consultant with customer focus, or
equivalent experience


Position3
Lucent Company
Title: Software Engineering Manager - Telecommunications Technology Centre

Location: Beijing, China
REQUIREMENTS:
.MS/PhD Computer Science, Engineering, or MBA with a science BS; 6-8 years of commercial software development experience on preference
in telecom domain (Telecom operator, Telecom equipment supplier…etc) with at
least 3-4 years as project manager for a team more than 8-10 people;
Strong verbal and written English skills.

If u have interests, pls send me your updated resume asap.Thanks
Contact ways:
0086 010 85999792
msn: lily81_europe@hotmail.com

Thursday, May 11, 2006

POJO Handling in J2EE environment

Case 1. Multiple threads simultaneously accessing one object instance.

Prerequisite: The object is statelss. (The object may have its own internal state, but does not maintain caller specific states.)

Example 1:
For POJO service facade implemented by Singleton, there is only one object instance of the facade class. For each user request, container will dispatch it to a thread picked from a thread pool. These threads will access this facade object instance concurrently. (Needs to be confirmed in WPS environment).

Example 2:
The default (MultiThreaded) mode of Servlet.

Case 2. Mutiple class instances to serve client requests.
Prerequistie: The object is stateful. And it is expensive to syncronize method access.

Example 1:
In SCM Sorter, since InterestLevelComparator is stateful object (to maintain cookie values), a new object instance is created per user request.

Example 2:
SingleThreaded model of Servlet. Servlet container may create multiple instances of the servlet class to serve multiple requests simultaneously.

Case 3. Partial/Whole Synchronization.
Prerequisite: The object is stateful. And it is expensive to create object instance per user request.

* Local variables: Each thread gets its own copy of the local variables, and changes made to these variables do not affect the copies of the local variables of other threads.
* Instance variables: there is only one copy of the instance variables per instance of the servlet, and all of the threads share this copy.
* Class variable: only one copy of a class variable exists across all the instances of the object
belonging to the class for which it is declared. Not surprisingly, just like instance variables, class
variables are not thread safe. In fact, class variables are unsafe even for the singlethreaded
model, because multiple threads may access the same class variable from different
servlet instances. Class variables are used to store “read-only,” or constant, data. Such data is
usually hard-coded in the class.

Pojo-based Middle Tier Vs. Thread Safe

A post popped up on the Spring mailing list regarding thread safety. The poster wanted to know if the "singleton, POJO-based service model" Spring recommends for a typical webapp is actually a good thing concurrency and scalability wise.

In my consulting work, I've been asked exactly this same question: When you're talking about a web-tier interfacing with a co-located, POJO-based middle tier, what does it mean to be "thread safe"? When do you have to worry about concurrency?

A guiding principle to heed is "never share caller specific (aka request specific) state between threads". Local variables are one way of achieving this (for example, declared within a thread-safe method of a request handler or servlet). ThreadLocals are another. A third is use of stateless service collaborators, the subject of this blog.

When you're talking about a traditional stateless service object--which is typically what these POJOs business facades are--a single instance typically serves all client requests. While such a singleton service may have its own internal state, it doesn't manage caller-specific state. Everything it needs from callers it gets within a caller's local thread of execution via method parameters. In addition, the internal collaborators these shared services often deal with: data sources, caches, transaction managers, or other resources, are already thread safe themselves (or they sure as heck better be!) :-)

Hence, there is no need to worry about synchronization within your service facades unless you manage shared read/write state yourself (an exceptional case in my experience). There is also no value in service instance pooling: a singleton stateless service object can serve all clients, and can easily be scaled across a cluster. There is value in resource pooling, but that's typically already handled transparently for you, by good infrastructure providers (like jakarta common's dbcp, for database connection pooling).

So, in summary, there is often no need to create a new, local service object per request (e.g a one shot "command object") unless there is caller specific state that object needs to be initialized with (in cases where the command pattern makes sense.) In the case where the per-request Command pattern does make sense, you can easily implement this "one-shot command" in Spring by declaring a prototype bean definition, retrieving a new instance instantiated, configured, and wired by the Spring IoC container on a per-request basis.

Trackback URL: http://jroller.com/trackback/kdonald/Weblog/when_shared_state_is_thread

How to make a program thread-safe

When multiple threads execute a single instance of a program and therefore share memory, multiple threads could possibly be attempting to read and write to the same place in memory.If we have a multithreaded program, we will have multiple threads processing the same instance.What happens when Thread-A examines instance variable x? Notice how Thread-B has just incremented instance variable x. The problem here is Thread-A has written to the instance variable x and is not expecting that value to change unless Thread-A explicitly does so. Unfortunately Thread-B is thinking the same thing regarding itself; the only problem is they share the same variable.

First method to make a program threadsafe: Avoidance

To ensure we have our own unique variable instance for each thread, we simply move the declaration of the variable from within the class to within the method using it. We have now changed our variable from an instance variable to a local variable. The difference is that, for each call to the method, a new variable is created; therefore, each thread has its own variable. Before, when the variable was an instance variable, the variable was shared for all threads processing that class instance. The following thread-safe code has a subtle, yet important, difference. This only applies to primitives. When it comes to actual Objects, the local variable does not make the program thread-safe since the variable just holding the reference to the unique object.

Second defense:Partial synchronization

Thread synchronization is an important technique to know, but not one you want to throw at a solution unless required. Anytime you synchronize blocks of code, you introduce bottlenecks into your system. When you synchronize a code block, you tell the JVM that only one thread may be within this synchronized block of code at a given moment. If we run a multithreaded application and a thread runs into a synchronized code block being executed by another thread, the second thread must wait until the first thread exits that block.

It is important to accurately identify which code block truly needs to be synchronized and to synchronize as little as possible. In our example, we assume that making our instance variable a local variable is not an option.

Third Defence: Whole synchronization

Here u should implement an interface which make the whole class a thread safe on or synchronized