標籤:java實現 close [] generate 位元組 instance .com nio bsp
原來項目中用openresty nginx+lua實現server,lua調用c動態連結程式庫,來使用openss做簽名,並產生130位元組(128簽名+2位自訂位元組)長度的檔案。
nginx: location /get/key { content_by_lua_file ‘/data/www/sign.lua‘; }sign.lualocal ffi = require "ffi"--動態連結gen_sig_ex_x.c,load("")名字規則,lib***.solocal gs = ffi.load("sin")ffi.cdef[[ int gen_main(char *param,unsigned char *signature)]]local param_ = ngx.var.arg_paramif param_ then local signature = ffi.new("unsigned char[130]", {}) local cpsn = ffi.new("char[20]", param_) gs.gen_main(param_, signature) ngx.header["Content-Disposition"] = "attachment; filename=" .. string.format("%s.%d.key", psn, key) ngx.header["Content-Length"] = 130 ngx.say(ffi.string(signature, 130))else ngx.header.content_type = "text/html" ngx.say("the param is not empty")end
對於sin.so用c與openssl實現了私密金鑰簽名,並使用RSA結構秘鑰,為順利得到pkcs8,在程式中通過如下代碼逆化了該格式的私密金鑰。並通過命令得到公開金鑰。
OpenSSL> genrsa -out rsa_private_key.pem 1024 #產生私密金鑰
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem #Java開發人員需要將私密金鑰轉換成PKCS8格式
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem #產生公開金鑰
OpenSSL> exit #退出OpenSSL程式
//根據RSA結構私密金鑰構建KEY對象,擷取私密金鑰公開金鑰base64: FILE *filename = NULL; filename = fopen("/data/www/unlock.lua/privateKey.pem", "wb"); //產生私密金鑰介面 PEM_write_RSAPrivateKey(filename, key, NULL, NULL, 0, NULL, NULL); fclose(filename); unsigned char *n_b = (unsigned char *)calloc(RSA_size(key), sizeof(unsigned char)); unsigned char *e_b = (unsigned char *)calloc(RSA_size(key), sizeof(unsigned char)); int n_size = BN_bn2bin(key->n, n_b); int b_size = BN_bn2bin(key->e, e_b); RSA *pubrsa = RSA_new(); pubrsa->n = BN_bin2bn(n_b, n_size, NULL); pubrsa->e = BN_bin2bn(e_b, b_size, NULL); FILE *publicKey = NULL; publicKey = fopen("/data/www/unlock.lua/publicKey.pem", "wb"); PEM_write_RSAPublicKey(publicKey, pubrsa); fclose(publicKey); RSA_free(pubrsa);
====java實現簽名核心代碼:package com.smartisan.genkey_sig.util;import org.apache.commons.codec.binary.Base64;import java.nio.charset.StandardCharsets;import java.security.KeyFactory;import java.security.PrivateKey;import java.security.Signature;import java.security.spec.PKCS8EncodedKeySpec;/** * desc: * * @author [email protected]*********.com * @since 2017/8/11 */public class RsaUtil { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; public static byte[] sign(byte[] data, String privateKey) { try { byte[] keyBytes = Base64.decodeBase64((privateKey)); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的密碼編譯演算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私密金鑰匙對象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私密金鑰對資訊產生數位簽章 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return signature.sign(); } catch (Exception ex) { throw new RuntimeException(ex); } } public static byte[] sign(String data, String privateKey) { return sign(data.getBytes(StandardCharsets.UTF_8), privateKey); }}
java翻譯lua+c+openssl簽名項目