我创建了一个示例项目,说明如何直接在Android上向时间戳提供者授权机构(在本示例中为freetsa)请求时间戳记文档。我做了研究,最接近的是使用BouncyCastle Java实现(链接到代码示例)。但这是行不通的。根据freetsa docs,我应该生成一个tsq文件并收到一个tsr。但是BouncyCastle使用对象TimeStampReq和TimeStampResponse。那些相等吗?有什么可以借鉴的例子吗?项目为here,相关代码如下。
private void createHash2() throws NoSuchAlgorithmException, IOException, TSPException {
// https:stackoverflow.com/questions/28085619/timestamping-using-tsa-url-and-java-apis
// for this sample we will use SHA1 to perform the hashes
// however feel free to use another algorithm since sha1 is weakness
String sha1Oid = "1.3.14.3.2.26";
// data to be timestamped
byte[] data = "some sample data... or your signature...".getBytes();
// perform the hash of your data
byte[] digestData = MessageDigest.getInstance(sha1Oid, new BouncyCastleProvider()).digest(data);
// generate random data to perform your ts, it's optional depends on your ts service
Random rand = new Random(new Date().getTime());
String nonce = BigInteger.valueOf(rand.nextLong()).toString();
// require cert optional (default false... so use false)
boolean requireCert = false;
// timestampPolicy it's an oid to identify a policy, if it's required
// must be provided by your ts service... it's optional so we put null
String timestampPolicy = null;
TimeStampReq ts_req = createTimeStampRequest(digestData, nonce, requireCert, sha1Oid, timestampPolicy);
// the data to be send to the service
try {
byte[] dataToSend = ts_req.getEncoded();
}
catch (IOException e) {
e.printStackTrace();
}
// simply send your data using POST method
// don't forget to specify http-header content-type as "application/timestamp-query"
byte[] response = makeHttpRequest();// send the request as you want
// parse the response
ASN1StreamParser asn1Sp = new ASN1StreamParser(response);
TimeStampResp tspResp = null;
try {
tspResp = TimeStampResp.getInstance((ASN1Sequence) asn1Sp.readObject());// new TimeStampResp((ASN1Sequence)asn1Sp.readObject());
}
catch (IOException e) {
e.printStackTrace();
}
TimeStampResponse tsr = new TimeStampResponse(tspResp);
// and get the timestamp token :)
TimeStampToken token = tsr.getTimeStampToken();
}
private byte[] makeHttpRequest() {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] result;
try {
URL url = new URL("https://freetsa.org/tsr");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/timestamp-query");
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.i(TAG, "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage());
return new byte[0];
}
File file = getExternalStorageDir("pdffile.tsr");
// download the file
input = connection.getInputStream();
output = new FileOutputStream(file);
long total = 0;
int count;
byte data[] = new byte[4096];
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
byteArrayOutputStream.write(data, 0, count);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (output != null) {
output.close();
}
if (input != null) {
input.close();
}
if (byteArrayOutputStream != null) {
result = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
return result;
}
}
catch (IOException e) {
e.printStackTrace();
}
if (connection != null) {
connection.disconnect();
}
}
return new byte[0];
}
public static TimeStampReq createTimeStampRequest(byte[] hashedData, String nonce, boolean requireCert, String digestAlgorithm, String timestampPolicy) {
MessageImprint imprint = new MessageImprint(new AlgorithmIdentifier(new ASN1ObjectIdentifier(digestAlgorithm)), hashedData);
TimeStampReq request = new TimeStampReq(
imprint,
timestampPolicy!=null ? new DERObjectIdentifier(timestampPolicy) : null,
nonce!=null ? new DERInteger(nonce.getBytes()) : null,
new DERBoolean(requireCert),
null
);
return request;
}
private File getExternalStorageDir(String fileName) {
// Get the directory for the user's public pictures directory.
File downloadDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
downloadDirectory.mkdirs();
return new File(downloadDirectory, fileName);
}