java 证书 生成 xml httpClient post 提交

java 证书公钥加密 生成xml 使用http post发送到servl et , servlet私钥解密
xml格式
1 :消息格式:
XML 消息格式如下:
<?xml version="1.0" encoding="UTF-8">
<Request>
<Head>
<Signed>Base64(sign((md5(LoginName + | + LoginTimeSpan + | + PassWord)))</Signed>
</Head>
<body>
<LoginName type="string"> Base64(DES(LoginName)</ LoginName>
<LoginTimeSpan type="string"> Base64(DES(LoginTimeSpan))</LoginTimeSpan>
<Password type="string"> Base64(DES(PassWord))(</Password>
</body>
</request>
2 :消息内容采用 DES 算法进行加密处理, DES 的入口参数有三个: Key Data IV 。其中 Key 8 个字节共 64 位,是 DES 算法的工作密钥; Data 也为 8 个字节 64 位,是需要进行加密的数据 ,IV 是双方协商好的初始化向量,要求双方一致,最后结果再进行 BASE64 编码处理,及 BASE64(DES( 传输的消息内容 ))
3 :发送方在消息体 <Head> 节点中对消息进行签名,防止消息内容在传输途中被篡改 , 由大众版那边提供公钥证书,这边对 Base64(md5(LoginName + | + LoginTimeSpan + | + PassWord)) 进行签名(rsa-sha1)





package  com.cmcc.common.util;

import  org.apache.commons.httpclient.HttpClient;
import  org.apache.commons.httpclient.HttpStatus;
import  org.apache.commons.httpclient.methods.PostMethod;
import  org.springframework.core.io.ClassPathResource;
import  sun.misc.BASE64Decoder;
import  sun.misc.BASE64Encoder;

import  javax.crypto.Cipher;
import  javax.crypto.SecretKey;
import  javax.crypto.SecretKeyFactory;
import  javax.crypto.spec.DESKeySpec;
import  javax.crypto.spec.IvParameterSpec;
import  javax.xml.bind.JAXBContext;
import  javax.xml.bind.Marshaller;
import  javax.xml.bind.Unmarshaller;
import  javax.xml.bind.annotation.XmlRootElement;
import  java.io. * ;
import  java.security. * ;
import  java.security.cert.Certificate;
import  java.security.cert.CertificateFactory;
import  java.util.Date;

/**
 * User: fengxuesong
 * Date: 11-3-29
 * Time: 下午12:03
 
*/
public   class  Sign {
    
// Des初始化向量 
     public   static   final   byte [] IV  =   new   byte []{ - 29 105 5 40 - 94 - 98 - 113 - 100 };
    
public   static   final  String prikey  =   " 00000000 " ;


    
public   static   void  main(String args[])  throws  Exception {
        String keystorePath 
=   " F:\\idea-projects\\OSP\\src\\main\\webapp\\WEB-INF\\classes\\feinno.keystore " ;

        String certPath 
=   " F:\\idea-projects\\OSP\\src\\main\\webapp\\WEB-INF\\classes\\feinno.cer " ;
        
        File keystoreFile
= new  ClassPathResource( " feinno.keystore " ).getFile();
        File certPathFile
= new  ClassPathResource( " feinno.cer " ).getFile();
        
if (keystoreFile != null ){
            keystorePath
= keystoreFile.getPath();
        }
        
if (certPathFile != null ){
            certPath
= certPathFile.getPath();
        }

        
// 初始化data
        String loginName  =   " 1 " ;
        String loginTimeSpan 
=   new  Date().toString();
        String password 
=   " 111111 " ;

        StringBuffer data 
=   new  StringBuffer();
        data.append(loginName).append(
" | " ).append(loginTimeSpan).append( " | " ).append(password);
        
// 生成 data  MD5加密
         byte [] headTextWithMD5  =  encryptWithMD5(data);

        
// ------------------私钥加密-----------------
        String storepass  =   " feinno " ; // 生成证书库时输入的密码
        String storeKeyName  =   " feinno " // 证书别名

        String headSigned 
=   new  BASE64Encoder().encode(sing(headTextWithMD5, storepass, storeKeyName,keystorePath));


        String content 
=  xml2String(encodeDesWithBase64(prikey, loginName), encodeDesWithBase64(prikey, loginTimeSpan), encodeDesWithBase64(prikey, password), headSigned);
        
// ---------------------发送http请求
        String url  =   " http://localhost:8080/auth " ;
        String backinfo 
=  sendPost(content, url);
        System.out.println(
" validate: "   +  backinfo);

        
// -----------------模拟 收到http请求 收到的xml 生成 bean
//         Request request = xml2Bean(content);
//         String acceptHeadSigned = request.getHead().getSigned();
//         String acceptLoginName = decodeDesWithBase64(prikey, request.getBody().getLoginName());
//         String acceptLoginTimeSpan = decodeDesWithBase64(prikey, request.getBody().getLoginTimeSpan());
//         String acceptPassword = decodeDesWithBase64(prikey, request.getBody().getPassword());
//         StringBuffer acceptData = new StringBuffer();
//         acceptData.append(acceptLoginName).append("|").append(acceptLoginTimeSpan).append("|").append(acceptPassword);
//          // -----------------公钥验证
//         byte[] verifyText = encryptWithMD5(acceptData); //  encryptWithMD5(acceptData);
//
//         boolean verifyFlag = verify(verifyText, new BASE64Decoder().decodeBuffer(acceptHeadSigned),certPath);
//         if (verifyFlag)
//             System.out.println("verify success");
//         else
//             System.out.println("verify faile");
    }

    
/**
     * 
@param  plainText  需要验证的内容
     * 
@param  headSigned 私钥生成的签名
     * 
@return
     
*/
    
public   static   boolean  verify( byte [] plainText,  byte [] headSigned,String certPath)  throws  Exception {

        InputStream streamCert 
=   new  FileInputStream(certPath);
        CertificateFactory factory 
=  CertificateFactory.getInstance( " X.509 " );
        Certificate cert 
=  factory.generateCertificate(streamCert);
        Signature rsa 
=  Signature.getInstance( " SHA1WithDSA " );
        PublicKey publicKey 
=  cert.getPublicKey();
        rsa.initVerify(publicKey);
        rsa.update(plainText);
        
if  (rsa.verify(headSigned)) {
            
return   true ;
        } 
else  {
            
return   false ;
        }
    }

    
/**
     * 
@param  plainText    签名的内容
     * 
@param  storepass    访问证书的密码
     * 
@param  storeKeyName 证书别名
     * 
@return
     
*/
    
public   static   byte [] sing( byte [] plainText, String storepass, String storeKeyName , String keystorePath)  throws  Exception {
        FileInputStream in 
=   new  FileInputStream(keystorePath);
        KeyStore ks 
=  KeyStore.getInstance( " JKS " );
        ks.load(in, storepass.toCharArray());
        
// 获取私钥
        PrivateKey priKey  =  (PrivateKey) ks.getKey(storeKeyName, storepass.toCharArray());
        
// 用私钥签名
        Signature sig  =  Signature.getInstance( " SHA1WithDSA " );
        sig.initSign(priKey);

        sig.update(plainText);
        
return  sig.sign();
    }

    
/**
     * 数据MD5加密
     *
     * 
@param  data
     * 
@return
     * 
@throws  NoSuchAlgorithmException
     
*/
    
public   static   byte [] encryptWithMD5(StringBuffer data)  throws  NoSuchAlgorithmException {
        MessageDigest md5 
=  MessageDigest.getInstance( " MD5 " );
        md5.update(data.toString().getBytes());
        
return  md5.digest();
    }


    
/**
     * 用 httpClient 发送 post请求
     *
     * 
@param  content 发送内容
     * 
@param  url
     * 
@return  返回 response
     * 
@throws  IOException
     
*/
    
public   static  String sendPost(String content, String url)  throws  IOException {
        String backinfo 
=   "" ;
        HttpClient httpclient 
=   new  HttpClient();
        
        httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(1000);
        PostMethod post = new PostMethod(url);
        post.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,500);

        post.setParameter(
" sign " , content);
        
try  {
            httpclient.executeMethod(post);
            
int  code  =  post.getStatusCode();
            
if  (code  ==  HttpStatus.SC_OK) {
                backinfo 
=   new  String(post.getResponseBodyAsString());
            }
        } 
finally  {
            post.releaseConnection();
        }
        
return  backinfo;
    }


    
/**
     * xml转bean
     *
     * 
@param  xml
     * 
@return
     
*/
    
public   static  Request xml2Bean(String xml)  throws  Exception {

        JAXBContext context 
=  JAXBContext.newInstance(Request. class );
        Unmarshaller um 
=  context.createUnmarshaller();
        InputStream inStream 
=   new  ByteArrayInputStream(xml.getBytes());
        Request request 
=  (Request) um.unmarshal(inStream);
        
return  request;
    }

    
/**
     * 生成xml对应的字符转
     *
     * 
@param  loginName     登录名
     * 
@param  loginTimeSpan 时间戳
     * 
@param  password      密码
     * 
@param  headSigned    证书鉴权
     * 
@return
     * 
@throws  Exception
     
*/
    
public   static  String xml2String(String loginName, String loginTimeSpan, String password, String headSigned)  throws  Exception {
        JAXBContext context 
=  JAXBContext.newInstance(Request. class );
        Request request 
=   new  Request();
        Head head 
=   new  Head();
        head.setSigned(headSigned);
        Body body 
=   new  Body();
        body.setLoginName(loginName);
        body.setLoginTimeSpan(loginTimeSpan);
        body.setPassword(password);
        request.setHead(head);
        request.setBody(body);
        Marshaller m 
=  context.createMarshaller();
        OutputStream outStream 
=   new  ByteArrayOutputStream();
        m.marshal(request, outStream);
        
return  outStream.toString();
    }

    
/**
     * 数据 Des加密, 并Base64编码, 解决 des 加密数据必须是8个字节的倍数
     *
     * 
@param  priKey 密钥
     * 
@param  data   需要加密的数据
     * 
@return  已加密数据
     
*/
    
public   static  String encodeDesWithBase64(String priKey, String data)  throws  Exception {
        DESKeySpec desKS 
=   new  DESKeySpec(priKey.getBytes());
        SecretKeyFactory skf 
=  SecretKeyFactory.getInstance( " DES " );
        SecretKey sk 
=  skf.generateSecret(desKS);
        Cipher cip 
=  Cipher.getInstance( " DES/CBC/PKCS5Padding " );
        cip.init(Cipher.ENCRYPT_MODE, sk, 
new  IvParameterSpec(IV));
        
byte  bb[]  =  cip.doFinal(data.getBytes());
        
return   new  BASE64Encoder().encode(bb);
    }

    
/**
     * 数据 Des解密,
     *
     * 
@param  priKey 密钥
     * 
@param  data   以加密数据
     * 
@return  解密数据
     * 
@throws  Exception
     
*/
    
public   static  String decodeDesWithBase64(String priKey, String data)  throws  Exception {
        DESKeySpec desKS 
=   new  DESKeySpec(priKey.getBytes());
        SecretKeyFactory skf 
=  SecretKeyFactory.getInstance( " DES " );
        SecretKey sk 
=  skf.generateSecret(desKS);
        Cipher cip 
=  Cipher.getInstance( " DES/CBC/PKCS5Padding " );
        cip.init(Cipher.DECRYPT_MODE, sk, 
new  IvParameterSpec(IV));
        
byte  bb[]  =  cip.doFinal( new  BASE64Decoder().decodeBuffer(data));
        
return   new  String(bb);
    }


    
/**
     * 生成xml的bean
     
*/
    @XmlRootElement
    
public   static   class  Request {
        
public  Request() {
        }

        Head head;
        Body body;

        
public  Head getHead() {
            
return  head;
        }

        
public   void  setHead(Head head) {
            
this .head  =  head;
        }

        
public  Body getBody() {
            
return  body;
        }

        
public   void  setBody(Body body) {
            
this .body  =  body;
        }
    }

    
public   static   class  Head {
        
public  Head() {
        }

        String signed;

        
public  String getSigned() {
            
return  signed;
        }

        
public   void  setSigned(String signed) {
            
this .signed  =  signed;
        }
    }

    
public   static   class  Body {
        
public  Body() {
        }

        String loginName;
        String loginTimeSpan;
        String password;

        
public  String getLoginName() {
            
return  loginName;
        }

        
public   void  setLoginName(String loginName) {
            
this .loginName  =  loginName;
        }

        
public  String getLoginTimeSpan() {
            
return  loginTimeSpan;
        }

        
public   void  setLoginTimeSpan(String loginTimeSpan) {
            
this .loginTimeSpan  =  loginTimeSpan;
        }

        
public  String getPassword() {
            
return  password;
        }

        
public   void  setPassword(String password) {
            
this .password  =  password;
        }
    }


}


你可能感兴趣的:(java 证书 生成 xml httpClient post 提交)