java 证书 生成 xml httpClient post 提交

Posted on 2011-05-13 11:50 xsong 阅读(1677) 评论(0)  编辑  收藏 所属分类: java
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[]{-29105540-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;
        }
    }


}



只有注册用户登录后才能发表评论。


网站导航: