java 加密 @ 7/28/2005

programming
由于工作需要,在网上google很多和 java 加密相关的东西,内容大都与Java加密和数字签名编程快速入门相似。

决定采用最简单的消息摘要的方法。

public void testDigest()
    {
        try
        {
            String myinfo = "cws123";
            java.security.MessageDigest alga = java.security.MessageDigest.getInstance("MD5");
            alga.update(myinfo.getBytes());
            byte[] digesta = alga.digest();           
            System.out.println("本信息摘要是:" + digesta);
            System.out.println("本信息摘要是 tostring:" + digesta.toString());
            System.out.println("本信息摘要是 tostring:" + new String(digesta));
            //通过某中方式传给其他人你的信息(myinfo)和摘要(digesta) 对方可以判断是否更改或传输正常
            java.security.MessageDigest algb = java.security.MessageDigest.getInstance("MD5");
            //java.security.MessageDigest algb = java.security.MessageDigest.getInstance("SHA-1");
            algb.update(myinfo.getBytes());   
            byte[] digestb = algb.digest();   
            if (MessageDigest.isEqual(digesta, digestb))
            {
                Log.print("信息检查正常");
                Log.print("1" + digesta.toString());
                Log.print("2" + digestb.toString());
            }
            else
            {
                Log.print("摘要不相同");
            }
            if ((new String(digesta,"UTF8")).equals(new String(digestb,"UTF8")))
            {
                Log.print(" 转换成字符串匹配一样 !");
            }
            //
        }
        catch (java.security.NoSuchAlgorithmException ex)
        {
            Log.print("非法摘要算法");
            ex.printStackTrace();
        } catch (UnsupportedEncodingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


这个方法是管用的,运行结果是
本信息摘要是:[B@18d107f
本信息摘要是 tostring:[B@18d107f
本信息摘要是 tostring:養驶栓=z>e
6m
信息检查正常
1[B@18d107f
2[B@45a877
转换成字符串匹配一样 !


存入数据库再读取的时候却不知道怎么处理了。
由于最初数据库设计的 password 字段是 varchar2(oracle),而加密以后只提供了 algb.digest() 返回 byte[],所以作了如下尝试
1.把 byte[] toString 存进数据库,rs.getString()以后getBytes(),调用MessageDigest.isEqual 和原始的密码再加密一次匹配,failed!
2.怀疑是编码解码格式的问题,于是都用“UTF8”编码或解码,failed!
3.在网上google搜到一篇关于用 BASE64 编码解码的文章:
Java中提供了计算报文摘要的另一个简单的方法,那就是使用java.security.MessageDigest类。下列代码片断显示了如何将MD5报文摘要算法(128位的摘要)应用到密码字符串:
MassageDigest md=
MessageDigest.getInstance("MD5");
md.update(originalPwd.getByetes());
byte[] digestedBytes=md.digest();

也使用报文摘要创建校验和、文本的唯一ID(也叫做数字指纹)。在签写ARJ文件会发生:校验和是根据ARJ文件的内容计算出来的,然后被加密,并且用 base64的加密格式存放在manifest.mf文件中。base64是编码任意二进制数据的一种方法,得到的结果仅包含可打印字符(注意, base64编码数据占用的空间比转换前多三分之一)。由于报文摘要算法输出的结果是字节数组,可以使用base64编码将哈希字节转换成字符串,以便能将该字符串存放在数据库的varchar字段中。现在有许多base64编码器,但是最简单的方法是使用weblogic.jar库中的编码器: weblogic.apache.xerces.utils.Base64。该类的作用微乎其微,如下面的代码例子所示:

String digestedPwdString =
new String(Base64.encode(digestedPwdBytes));

于是采用,最终还是 failed!

于是将数据库的password 字段改成 Blob,发现存进去和读取出来的byte[]不一样,也许是读写的方式有问题。

如果要把一个二制文件存入ORACLE,用标准的JDBC你就要用LONG ROW类型:
create table tb_file(name varchar(20),detail long row);
然后
File file = new File("aaa.gif");
int fileLength =(int) file.length();
InputStream fin = new FileInputStream(file);
PreparedStatement pstmt = con.prepareStatement("insert into tb_file values('aaa.gif',?)");
pstmt.setBinaryStream (1, fin, fileLength);
pstmt.executeUpdate();

如果你一定要用BLOB存储,你就必须用ORACLE自己的方法:
create table tb_file(name varchar(20),detail BLOB);
con.setAutoCommit(false);
stmt.executeUpdate("insert into tb_file values('aaa.gif',empty_blob())");
下面必须SELECT得到BLOB的对象再向里写:
rs = stmt.executeQuery("select detail from tb_file where name='aaa.gif' for upfdate" );
if(rs.next())
{
Blob blob = rs.getBlob(1);
BinaryOutputStream out = ((oracle.sql.BLOB)blob).getBinaryOutputStream();
byte[] b = new byte[((oracle.sql.BLOB)blob).getBufferSize];
InputStream fin = new FileInputStream(file);
int len = 0;
while( (len = fin.read(b)) != -1)
out.write(b,0,len);
fin.close();
out.close();
con.commit();
}

于是再改程序按这个方式读写,仍然尚未走通
继续摸索中......

我是编程菜鸟,有高手可指点否?

发布于 7/28/2005 12:24:04 | 评论:2
小毛 @ 7/28/2005 12:37:59
精神支持一下~~~

俺也不懂~~~沙发,等着看高手解答~~~
gai @ 7/28/2005 13:13:07
非常感谢 ss 的大力帮忙,最终把数据库 password 字段换成long RAW,读写的时候直接 rs.getBytes(),pstmt.setBinaryStream()能保证读出来和写进去的二进制数组完全一样,于是问题也就可以解决了。

但是还是有点纳闷,难道别人的软件里都是这么解决,应该还有更好的方式吧

看帖要回帖...

Loading...

我不去想是否能够成功
既然选择了远方
便只顾风雨兼程

我不去想能否赢得爱情
既然钟情于玫瑰
就勇敢地吐露真诚

我不去想身后会不会袭来寒风冷雨
既然目标是地平线
留给世界的只能是背影

我不去想未来是平坦还是泥泞
只要热爱生命
一切,都在意料中

----汪国真《热爱生命》
categories
archives
links
statistics
  • 网志数:221
  • 评论数:1313