利用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[]{-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;
}
}


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于利用DES算法加密解密学号的JAVA代码实现,我将为您提供以下代码: ``` import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; public class DES { private static final String KEY = "12345678"; // 这里将密钥定义为 12345678 // 加密方法 public static String encrypt(String data) throws Exception { // 创建一个DESKeySpec对象,并传入密钥 DESKeySpec desKeySpec = new DESKeySpec(KEY.getBytes()); // 创建一个SecretKeyFactory对象 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); // 通过SecretKeyFactory对象将DESKeySpec转换成SecretKey对象 SecretKey secretKey = keyFactory.generateSecret(desKeySpec); // 创建一个Cipher对象,并指定加密算法 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // 初始化Cipher对象,指定为加密模式,并传入密钥 cipher.init(Cipher.ENCRYPT_MODE, secretKey); // 调用Cipher对象的doFinal方法进行加密 byte[] encryptedData = cipher.doFinal(data.getBytes()); // 将加密后的byte数组转换成十六进制字符串,并返回 return byteArrayToHexString(encryptedData); } // 解密方法 public static String decrypt(String encryptedData) throws Exception { // 创建一个DESKeySpec对象,并传入密钥 DESKeySpec desKeySpec = new DESKeySpec(KEY.getBytes()); // 创建一个SecretKeyFactory对象 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); // 通过SecretKeyFactory对象将DESKeySpec转换成SecretKey对象 SecretKey secretKey = keyFactory.generateSecret(desKeySpec); // 创建一个Cipher对象,并指定加密算法 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // 初始化Cipher对象,指定为解密模式,并传入密钥 cipher.init(Cipher.DECRYPT_MODE, secretKey); // 将十六进制字符串转换成byte数组 byte[] data = hexStringToByteArray(encryptedData); // 调用Cipher对象的doFinal方法进行解密 byte[] decryptedData = cipher.doFinal(data); // 将解密后的byte数组转换成字符串,并返回 return new String(decryptedData); } // 将byte数组转换成十六进制字符串 private static String byteArrayToHexString(byte[] byteArray) { StringBuilder sb = new StringBuilder(); for (byte b : byteArray) { String hex = Integer.toHexString(0xFF & b); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); } // 将十六进制字符串转换成byte数组 private static byte[] hexStringToByteArray(String hexString) { int len = hexString.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i+1), 16)); } return data; } } ``` 以上是一个简单的DES加密解密算法JAVA代码实现,您可以直接调用该类的encrypt和decrypt方法,对学号进行加密解密。例如: ``` String studentId = "1900012345"; // 要加密的学号 String encryptedId = DES.encrypt(studentId); // 加密后的学号 System.out.println(encryptedId); // 输出加密后的学号 String decryptedId = DES.decrypt(encryptedId); // 解密后的学号 System.out.println(decryptedId); // 输出解密后的学号 ``` 请注意,以上仅仅是一个简单的DEA算法实现代码示例,实际应用场景中需要考虑更多的实际问题,例如密钥的保护、算法的安全性等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值