package hamaster.gradesgin.ibe.core;
import hamaster.gradesgin.ibe.IBECipherText;
import hamaster.gradesgin.ibe.IBEConstraints;
import hamaster.gradesgin.ibe.IBEPlainText;
import hamaster.gradesgin.ibe.IBEPrivateKey;
import hamaster.gradesgin.ibe.IBEPublicParameter;
import hamaster.gradesgin.ibe.IBESystemParameter;
import hamaster.gradesgin.ibs.IBSCertificate;
import hamaster.gradesgin.ibs.IBSSignature;
import hamaster.gradesgin.util.Hash;
import hamaster.gradesign.ibe.IBELibrary;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;
/**
* 基于身份加密(IBE)的核心库,提供相关的方法
* Core utils of IBE
* @author <a href="mailto:wangyeee@gmail.com">Wang Ye</a>
*/
public class IBEEngine {
/**
* 初始化一个IBE系统
* Setup an IBE system
* @param pairingIn 椭圆函数参数 the pairing
* @return 系统参数 如果椭圆函数参数非法或者出现其它错误返回null
* returns the IBESystemParameter object when success, otherwise return null
*/
public static IBESystemParameter setup(byte[] pairingIn) {
byte[] alphaOut = new byte[IBELibrary.PBC_ZR_SIZE];
byte[] gOut = new byte[IBELibrary.PBC_G_SIZE];
byte[] g1Out = new byte[IBELibrary.PBC_G_SIZE];
byte[] hOut = new byte[IBELibrary.PBC_G_SIZE];
int succ = IBELibrary.setup(alphaOut, gOut, g1Out, hOut, pairingIn);
if (succ == 0) {
IBEPublicParameter publicParameter = new IBEPublicParameter();
publicParameter.setParamG(gOut);
publicParameter.setParamG1(g1Out);
publicParameter.setParamH(hOut);
publicParameter.setPairing(pairingIn);
IBESystemParameter parameter = new IBESystemParameter();
parameter.setMasterKey(alphaOut);
parameter.setPublicParameter(publicParameter);
return parameter;
}
return null;
}
/**
* 为一个用户生成私钥
* Generate a private key for a user
* @param system IBE系统 the system parameter
* @param user 私钥请求用户 the user
* @return 用户的私钥 the generated private key
*/
public static IBEPrivateKey keygen(IBESystemParameter system, String user) {
byte[] hIDOut = new byte[IBELibrary.PBC_G_SIZE];
byte[] rIDOut = new byte[IBELibrary.PBC_ZR_SIZE];
try {
int succ = IBELibrary.keygen(hIDOut, rIDOut, user.getBytes(IBEConstraints.USER_STRING_ENCODING), system.getMasterKey(), system.getPublicParameter().getParamG(), system.getPublicParameter().getParamH(), system.getPublicParameter().getPairing());
if (succ != 0)
throw new IOException("Cannot generate private key for user:" + user);
IBEPrivateKey privateKey = new IBEPrivateKey();
privateKey.sethID(hIDOut);
privateKey.setrID(rIDOut);
privateKey.setUserString(user);
privateKey.setPairing(system.getPublicParameter().getPairing());
return privateKey;
} catch (IOException e) {
return null;
}
}
/**
* 对数据进行加密
* encryption
* @param publicParameter 接收方公共参数 the recipients' public key
* @param plainText 明文 the plain text
* @param receiver 接收着身份 the recipient
* @return 密文 cipher text
*/
public static IBECipherText encrypt(IBEPublicParameter publicParameter, IBEPlainText plainText, String receiver) {
byte[] cipherBufferOut = new byte[IBELibrary.PBC_G_SIZE * 3];
try {
int succ = IBELibrary.encrypt(cipherBufferOut, plainText.getContent(), publicParameter.getParamG(), publicParameter.getParamG1(), publicParameter.getParamH(), receiver.getBytes(IBEConstraints.USER_STRING_ENCODING), publicParameter.getPairing());
if (succ != 0)
throw new IOException("Cannot encrypt messege for user:" + receiver);
IBECipherText cipherText = new IBECipherText();
cipherText.setUvw(cipherBufferOut);
cipherText.setLength(plainText.getLength());
return cipherText;
} catch (IOException e) {
return null;
}
}
/**
* 对密文解密
* decryption
* @param cipherText 密文
* @param privateKey 接收方私钥
* @return 解密后明文 plain text
*/
public static IBEPlainText decrypt(IBECipherText cipherText, IBEPrivateKey privateKey) {
byte[] plainBufferOut = new byte[IBELibrary.PBC_G_SIZE];
int i = IBELibrary.decrypt(plainBufferOut, cipherText.getUvw(), privateKey.getrID(), privateKey.gethID(), privateKey.getPairing());
if (i == 0) {
IBEPlainText plainText = new IBEPlainText() {
private static final long serialVersionUID = -2705082103669151761L;
};
plainText.setContent(plainBufferOut);
plainText.setLength(cipherText.getLength());
return plainText;
}
return null;
}
/**
* 生成证书
* Generate certificate
* @param user 证书所有者 certificate owner
* @param root 签名用根证书 如果生成根证书 则传入一个只包含椭圆函数信息的证书对象
* the root certificate, if this paramater only contains a pairing, then this method will generate a root certificate
* @param validAfter 有效期开始日期 the certificate effective start date
* @param period 有效时间 单位毫秒 the certificate valid time period, in millisecond.
* @return 生成的证书 the certificate
*/
public static IBSCertificate generateCertificate(String user, IBSCertificate root, Date validAfter, long period) {
IBSCertificate root0 = root;
IBESystemParameter parameter = setup(root0.getPublicParameter().getPairing());
IBSCertificate certificate = new IBSCertificate();
certificate.setMasterKey(parameter.getMasterKey());
certificate.setPublicParameter(parameter.getPublicParameter());
certificate.setOwnerString(user);
certificate.setNoEarlyThan(validAfter);
certificate.setNoLateThan(new Date(period + validAfter.getTime()));
if (root0.getMasterKey() == null)
root0 = certificate;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream writer = new ObjectOutputStream(out);
writer.writeObject(certificate);
writer.flush();
writer.close();
byte[] data = out.toByteArray();
out.close();
byte[] hash = Hash.sha256(data);
IBSSignature signature = sign(root0, hash, "SHA-256");
certificate.setSignature(signature);
return certificate;
} catch (IOException e) {
return null;
}
}
/**
* 进行数字签名
* Digital signing prcess
* @param certificate 签名证书
* @param digest 待签名数据摘要
* @param hash 摘要方法 e.g. SHA1 or MD5
* @return 数字签名
*/
public static IBSSignature sign(IBSCertificate certificate, byte[] digest, String hash) {
IBSSignature signature = new IBSSignature();
signature.setSignatureParameter(certificate.getPublicParameter());
signature.setDigest(digest);
signature.setHashAlgorithm(hash);
signature.setSigningDate(new Date());
try {
IBEPrivateKey privateKey = keygen(certificate, new String(digest, IBEConstraints.USER_STRING_ENCODING));
signature.sethID(privateKey.gethID());
signature.setrID(privateKey.getrID());
signature.setUserString(privateKey.getUserString());
return signature;
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* 验证数字签名
* Verify a digital signature
* @param signature 数字签名
* @param digest 待验证数据摘要
* @return 当且仅当数据一致且签名合法时验证通过 only if the verification passes it returns true
*/
public static boolean verify(IBSSignature signature, byte[] digest) {
if (signature == null || digest == null)
return false;
boolean integrity = Arrays.equals(digest, signature.getDigest());
if (!integrity)
return false;
byte[] significantBytes = new byte[120];
new Random().nextBytes(significantBytes);
IBEPlainText plainText = IBEPlainText.newIbePlainTextFormSignificantBytes(significantBytes);
try {
IBECipherText cipherText = encrypt(signature.getSignatureParameter(), plainText, new String(digest, IBEConstraints.USER_STRING_ENCODING));
IBEPlainText decrypt = decrypt(cipherText, signature);
return decrypt.equals(plainText);
} catch (UnsupportedEncodingException e) {
return false;
}
}
}