在Java和.NET平台的加密术比较

最近在写一个Java的消息服务器,同时需要做一个.NET版本的客户端。他们之间需要安全通讯,基于一些简单的密码协议,用到公钥加密、对称加密、Hash算法。这个过程中,我对这两个平台的加密部分有了一定了解,以下也是我的一些新的认识吧。

1、对称加密
1) Java 1.5的对称加密很简单,提供的算法也较多。可以说是,使用简单,傻瓜式,而且功能齐全。
例如:
SecretKeySpec skeySpec  =   new  SecretKeySpec(key,  " AES " );

Cipher cipher 
=  Cipher.getInstance( " AES " );
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte [] decryptText  =  cipher.doFinal(data);

2) .NET 2.0的对称加密,缺省加密模式是CBC,CBC加密的时候,需要一个密钥的同时,还需要初始化向量IV,这会使得初学入者使用起来不方便,这个问题到是十分容易对付的,修改一下配置就好了。
SymmetricAlgorithm algorithm  =  SymmetricAlgorithm.Create(algorithmName);
algorithm.Mode 
=  CipherMode.ECB;
algorithm.Key 
=  key;
algorithm.Padding 
=  PaddingMode.PKCS7;
通过这种设置之后,就能够跟Java通讯操作,互为加密解密。

3) .NET 2.0和Java 1.5方面,加密算法的名字有些地方稍有差别。
AES <==> Rijndael
DESede <==> TripleDES
这是似乎是常识。


2、公钥加密算法RSA
1) Java 1.5中,RSAPublicKey进行getEncoded()得到字节数组是ASN.1编码的。逆转回来需要使用X509EncodedKeySpec,这个细节需要阅读文档细节或者对密码学有一定了解才知道。例如:
// public key ==> bytes
PublicKey publicKey  =  
byte [] rawPublicKey  =  publicKey.getEncoded();

//  bytes ==> public key
X509EncodedKeySpec x509KeySpec  =   new  X509EncodedKeySpec(rawPublicKey);
KeyFactory keyFactory 
=  KeyFactory.getInstance( " RSA " );
Key newPublicKey 
=  keyFactory.generatePublic(x509KeySpec);

除此之外,Java的公钥加密部分,还是相当易于使用的。风格依然是功能简单,傻瓜式使用,功能齐全。

Java中,支持ASN.1编码,但是隐藏其中,使用者完全觉察不到。

2) .NET 2.0中,设计有些混乱,并不支持ASN.1编码。但是Mono似乎在做ASN.1编码的支持。为此我自己借鉴一个Java开元JCE的实现,实现了一个.NET版本的ASN Parser和ASN Builder,花了两天时间。如下:
public   static  RSAParameters ASN1ToPublicKey( byte [] rawPublicKey)
{
    ASN1InputStream asnInput 
=   new  ASN1InputStream(rawPublicKey);
    ASN1Sequence asnSeq 
=  (ASN1Sequence)asnInput.ReadObject();
    SubjectPublicKeyInfo subjectPublicKeyInfo 
=   new  SubjectPublicKeyInfo(asnSeq);

    DERObjectIdentifier algOid 
=  subjectPublicKeyInfo.AlgorithmId.ObjectId;

    RSAPublicKeyStructure pubKey 
=   new  RSAPublicKeyStructure(
            (ASN1Sequence)subjectPublicKeyInfo.PublicKey);

    
byte [] modulus  =  pubKey.Modulus;
    
byte [] publicExponent  =  pubKey.PublicExponent;

    RSAParameters pram 
=   new  RSAParameters();
    pram.Modulus 
=  modulus;
    pram.Exponent 
=  publicExponent;

    RSACryptoServiceProvider rsa 
=   new  RSACryptoServiceProvider();
    rsa.ImportParameters(pram);

    
return  pram;
}

public   static   byte [] PublicKeyToASN1(RSAParameters pram)
{
    SubjectPublicKeyInfo info 
=   new  SubjectPublicKeyInfo(
        
new  AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption,
                
new  DERNull()),  new  RSAPublicKeyStructure(pram.Modulus, pram.Exponent).DERObject);

    
byte [] rawPublicKey  =  info.GetDEREncoded();
    
return  rawPublicKey;
}


3、总体感觉
1) Java的安全模块设计得还是很好的,简单易用,功能也齐全。
2) .NET 2.0则是有点乱,命名风格和系统框架有些不协调,功能欠缺,代码组织的不够理想。
3) 在Mono中,对安全的支持要比微软已发布的要好,从网上可以看到,.NET Framework 2.0的一些特性也是从Mono中借鉴过来的。
4) 甚至可以认为,.NET加密模块的开发团队能力可能不是很强。就如那一句话“编写糟糕的代码并非我们的专利”。




你可能感兴趣的:(java,密码学)