android平台使用java动态生成公私钥,并导出证书文件
生活随笔
收集整理的這篇文章主要介紹了
android平台使用java动态生成公私钥,并导出证书文件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
不依賴keytool工具,指令生成證書庫,而是java代碼生成,且導出到證書文件中。直接上代碼:
證書工具類:
package com.daobo.security.utilsimport com.daobo.security.bean.Certification import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.x509.X509V1CertificateGenerator import sun.misc.BASE64Decoder import sun.misc.BASE64Encoder import java.io.BufferedInputStream import java.io.FileInputStream import java.math.BigInteger import java.security.* import java.security.Security.addProvider import java.security.cert.CertificateFactory import java.security.cert.X509Certificate import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.RSAKeyGenParameterSpec import java.util.* import javax.security.auth.x500.X500Principalobject CertificationUtil {const val strDnInfo : String = "CN=Test Certificate"/*** @param pair 密鑰對* @param startDate 有效期* @param endDate 有效期* @param info 證書信息* @return* @throws InvalidKeyException* @throws NoSuchProviderException* @throws SignatureException*/@Throws(InvalidKeyException::class, NoSuchProviderException::class, SignatureException::class)@SuppressWarnings("deprecation")fun generateV1Certificate(pair: KeyPair, startDate: Date, endDate: Date, info: X500Principal): X509Certificate {// generate the certificateaddProvider(BouncyCastleProvider())val certGen = X509V1CertificateGenerator()certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()))certGen.setIssuerDN(info)certGen.setNotBefore(startDate)certGen.setNotAfter(endDate)certGen.setSubjectDN(X500Principal(strDnInfo))certGen.setPublicKey(pair.public)// i get error herecertGen.setSignatureAlgorithm("SHA256WithRSAEncryption")return certGen.generateX509Certificate(pair.private, "BC")}/*** * 生成證書文件* @param address 文件保存的路徑* @param startDate 有效期* @param endDate 有效期* @param info 證書信息* @param algorithm 算法名稱* @param keySize 密鑰長度* @param random 隨機源* @throws Exception*/@Throws(Exception::class)fun writeFilePkCert(fileName: String, startDate: Date, endDate: Date, info: X500Principal,algorithm: String, keySize: Int, random: SecureRandom, kpGen : Certification) {// create the keysval kp = kpGen.getKeyPair(algorithm, keySize, random)// generate the certificateval cert = generateV1Certificate(kp, startDate, endDate, info)// show some basic validationcert.checkValidity(Date())cert.verify(cert.publicKey)CertFileUtil.getInstance(null).writeToFile(fileName,BASE64Encoder().encode(cert.encoded))//System.out.println("valid certificate generated:"+cert.getPublicKey());}@Throws(Exception::class)fun writeFileSkCert(fileName: String, kpGen : Certification) {//直接將私鑰 string 寫進到文件CertFileUtil.getInstance(null).writeToFile(fileName,getKeyAsString(kpGen.privateKey!!))//System.out.println("valid certificate generated:"+cert.getPublicKey());}fun getKeyAsString(key: Key): String {val keyBytes = key.encodedval b64 = BASE64Encoder()return b64.encode(keyBytes)}//將String類型轉換為PrivateKey類型@Throws(Exception::class)fun getPrivateKeyFromString(key: String, algorithm: String): PrivateKey {val keyFactory = KeyFactory.getInstance(algorithm)val b64 = BASE64Decoder()val privateKeySpec = PKCS8EncodedKeySpec(b64.decodeBuffer(key))return keyFactory.generatePrivate(privateKeySpec)}/*** 獲取證書對象* @param address 證書文件路徑* @return* @throws Exception*/@Throws(Exception::class)fun getCert(address: String): X509Certificate? {var cert: X509Certificate? = nullval fis = FileInputStream(address)val bis = BufferedInputStream(fis)val cf = CertificateFactory.getInstance("X.509")while (bis.available() > 0) {cert = cf.generateCertificate(fis) as X509Certificate?}return cert} }certification Bean:
package com.daobo.security.beanimport java.math.BigInteger import java.security.* import java.text.SimpleDateFormat import java.util.* import javax.crypto.Cipherclass Certification {var strName : String = ""var strCreateTime : String = ""var strEffectiveTime : String = ""// 私鑰:var privateKey: PrivateKey? = null// 公鑰:var publicKey: PublicKey? = nullconstructor(name : String, createTime : String, effectiveTime: String){strName = namestrCreateTime = createTimestrEffectiveTime = effectiveTime}constructor(name : String, effectiveTime : String) {this.strName = namethis.strEffectiveTime = effectiveTimeval format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")strCreateTime = format.format(Date())}@Throws(GeneralSecurityException::class, NoSuchAlgorithmException::class)fun getKeyPair(algorithm : String, keySize : Int, random : SecureRandom) : KeyPair {val kpGen = KeyPairGenerator.getInstance(algorithm)kpGen.initialize(keySize, random)val keyPair = kpGen.generateKeyPair()this.privateKey = keyPair!!.privatethis.publicKey = keyPair!!.publicreturn keyPair}fun isExpired () : Boolean {var date = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(strEffectiveTime)if(date.before(Date())){return true}return false}// 把私鑰導出為字節fun getPrivateKey(): ByteArray {return this.privateKey!!.encoded}// 把公鑰導出為字節fun getPublicKey(): ByteArray {return this.publicKey!!.encoded}// 用公鑰加密:@Throws(GeneralSecurityException::class)fun encrypt(message: ByteArray): ByteArray {val cipher = Cipher.getInstance("RSA")cipher.init(Cipher.ENCRYPT_MODE, this.publicKey)return cipher.doFinal(message)}// 用私鑰解密:@Throws(GeneralSecurityException::class)fun decrypt(input: ByteArray): ByteArray {val cipher = Cipher.getInstance("RSA")cipher.init(Cipher.DECRYPT_MODE, this.privateKey)return cipher.doFinal(input)} }寫文件的工具類:
package com.daobo.security.utilsimport android.content.Context import android.os.Environment import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.io.OutputStreamWriter import java.nio.charset.Charsetclass CertFileUtil {private var applicationContext : Context? = nullvar certRootPath : String = ""companion object {private var instance: CertFileUtil? = nullfun getInstance(context: Context?): CertFileUtil {if (instance == null)instance = CertFileUtil(context)return instance!!}}private constructor (context: Context?) {this.applicationContext = contextLogUtil.init(LogUtil.INFO_LEVEL, "$certRootPath/daobo/log/")val state = Environment.getExternalStorageState()if (Environment.MEDIA_MOUNTED == state) {// 已經掛載了sd卡certRootPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePathcertRootPath += "/daobo/cert/"} else {LogUtil.info( "=== 讀取 sd 狀態不可用!===")}}fun certPKFileName (certName : String) : String {return certName + "_pk.cer"}fun certSKFileName (certName : String) : String {return certName + "_sk.cer"}fun writeToFile(fileName : String, fileData : String) {try {val filePath = File(certRootPath)if (!filePath.exists()) {filePath.mkdirs()}val file = File(filePath, fileName)val fos = FileOutputStream(file)val wr = OutputStreamWriter(fos, Charset.forName("UTF-8"))//wr.write("-----BEGIN CERTIFICATE-----\n")wr.write(fileData)//wr.write("\n-----END CERTIFICATE-----\n")wr.flush()wr.close()//val fos = FileOutputStream(file)//fos.write(fileData)//fos.flush()fos.close()}catch (e:Exception) {e.printStackTrace()}}fun readCertFile(fileName : String) : ByteArray {var filePath = File(certRootPath)var files = filePath.listFiles()if(files == null || files.isEmpty()){//Toast.makeText(context, "文件為空!", Toast.LENGTH_SHORT).show()LogUtil.info("directory=daoboCert=== 文件為空!===")return ByteArray(0)}// 拿到輸入流for(f in files){if(fileName == f.name){val input = FileInputStream(files[0])try {// 建立存儲器var buf = ByteArray(input.available())// 讀取到存儲器input.read(buf)return buf} catch (e: Exception) {e.printStackTrace()}finally {// 關閉輸入流input.close()}}}return ByteArray(0)}}說明下,需要依賴一個證書的庫:bcprov-jdk15to18-165.jar?(bouncycastle)鏈接,還需要單獨去下載一個Android使用的base64編碼的工具jar
公鑰是有對應的生成cer證書的操作,但是私鑰沒有,一半經過base64直接寫到文件中。公鑰證書有幾個關鍵的證書參數:
//獲取發布者標識 Principal principalIssuer = x509Certificate.getIssuerDN(); //獲取證書的主體標識 Principal principalSubject = x509Certificate.getSubjectDN(); //保存證書的序列號 list.add(x509Certificate.getSerialNumber())?
?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的android平台使用java动态生成公私钥,并导出证书文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 街道领导班子庸懒散浮拖整治工作报告3篇
- 下一篇: 四月什么水果当季