加密這種程式設計師在開發的時候也是非常重要的,本文我們主要介紹Java加密解密和數位簽章完整程式碼範例,希望可以幫助到大家。
常見的加密演算法
基本的單向加密演算法:
BASE64嚴格地說,屬於編碼格式,而非加密演算法
MD5(MessageDigestalgorithm5,資訊摘要演算法)
SHA(SecureHashAlgorithm,安全雜湊演算法)
HMAC(HashMessageAuthenticationCode,散列訊息鑑別碼)
#複雜的對稱加密(DES、PBE)、非對稱加密演算法:
DES(DataEncryptionStandard,資料加密演算法)
PBE(Password-basedencryption,基於密碼驗證)
RSA(演算法的名字以發明者的名字命名:RonRivest,AdiShamir和LeonardAdleman)
DH(Diffie-Hellman演算法,金鑰一致協定)
DSA(DigitalSignatureAlgorithm,數位簽章)
ECC(EllipticCurvesCryptography,橢圓曲線密碼編碼學)
數位簽章
演算法簡述
數位簽章演算法可以看做是一種帶有金鑰的訊息摘要演算法,而這種密鑰包含了公鑰和私鑰。也就是說,數位簽章演算法是不對稱加密演算法和訊息摘要演算法的結合。
特點
數位簽章演算法要求能夠驗證資料完整性、認證資料來源,並起到抗否認的作用。
原理
數位簽名演算法包含簽名和驗證兩項操作,遵循私鑰簽名,公鑰驗證的方式。
簽名時要使用私鑰和待簽章數據,驗證時則需要公鑰、簽章值和待簽章數據,其核心演算法主要是訊息摘要演算法。
1. 訊息摘要
String beforeDegist = "asdf"; System.out.println("摘要前:"+beforeDegist); //初始信息要转换成字节流的形式 byte[] plainText = beforeDegist.getBytes("UTF8"); //使用getInstance("算法")来获得消息摘要,这里使用SHA-1的160位算法或者MD5算法 geDigest messageDigest = MessageDigest.getInstance("SHA-1"); MessageDigest messageDigest = MessageDigest.getInstance("MD5"); System.out.println("/n" + messageDigest.getProvider().getInfo()); //开始使用算法 messageDigest.update(plainText); //输出算法运算结果 String afterDegist = new String(messageDigest.digest(),"UTF8"); System.out.println("摘要后:"+afterDegist);
#2. 私密金鑰加密
/** * 此例子是对一个字符串信息,用一个私钥(key)加密,然后在用该私钥解密,验证是否一致 * 私钥加密,是对称加密 * 使用对称算法。比如:A用一个密钥对一个文件加密,而B读取这个文件的话,则需要和A一样的密钥,双方共享一 * 个私钥(而在web环境下,私钥在传递时容易被侦听) * * 附:主要对称算法有:DES(实际密钥只用到56 位) * AES(支持三种密钥长度:128、192、256位),通常首先128位,其他的还有DESede等 */ <span style="white-space: pre; "> </span>String before = "asdf"; byte[] plainText = before.getBytes("UTF8"); // STEP 1.
System.out.println("Start generate AES key."); //得到一个使用AES算法的KeyGenerator的实例 KeyGenerator keyGen = KeyGenerator.getInstance("AES"); //定义密钥长度128位 keyGen.init(128); //通过KeyGenerator产生一个key(密钥算法刚才已定义,为AES) Key key = keyGen.generateKey(); System.out.println("Finish generating AES key="+key);
//STEP 2.
//获得一个私钥加密类Cipher,定义Cipher的基本信息:ECB是加密方式,PKCS5Padding是填充方法 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); //System.out.println("/n" + cipher.getProvider().getInfo());
//STEP 3.
// 使用私钥加密 System.out.println("/n用私钥加密..."); // 把刚才生成的key当作参数,初始化使用刚才获得的私钥加密类,Cipher.ENCRYPT_MODE意思是加密 cipher.init(Cipher.ENCRYPT_MODE, key); //私钥加密类Cipher进行加密,加密后返回一个字节流byte[] byte[] cipherText = cipher.doFinal(plainText); //以UTF8格式把字节流转化为String String after1 = new String(cipherText, "UTF8"); System.out.println("用私钥加密完成:"+after1);
[java] view plain copy //使用私钥对刚才加密的信息进行解密,看看是否一致,Cipher.DECRYPT_MODE意思是解密钥 System.out.println("/n用私钥解密..."); cipher.init(Cipher.DECRYPT_MODE, key); //对刚才私钥加密的字节流进行解密,解密后返回一个字节流byte[] byte[] newPlainText = cipher.doFinal(cipherText); String after2 = new String(newPlainText, "UTF8"); System.out.println("用私钥解密完成:"+after2);
String before = "asdf"; byte[] plainText = before.getBytes("UTF8"); //产生一个RSA密钥生成器KeyPairGenerator(顾名思义:一对钥匙生成器) KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); //定义密钥长度1024位 keyGen.initialize(1024); //通过KeyPairGenerator产生密钥,注意:这里的key是一对钥匙!! KeyPair key = keyGen.generateKeyPair(); //获得一个RSA的Cipher类,使用公钥加密 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); //System.out.println("/n" + cipher.getProvider().getInfo()); System.out.println("/n用公钥加密..."); //Cipher.ENCRYPT_MODE意思是加密,从一对钥匙中得到公钥 key.getPublic() cipher.init(Cipher.ENCRYPT_MODE, key.getPublic()); //用公钥进行加密,返回一个字节流 byte[] cipherText = cipher.doFinal(plainText); //以UTF8格式把字节流转化为String String after1 = new String(cipherText, "UTF8"); System.out.println("用公钥加密完成:"+after1); //使用私钥解密 System.out.println("/n用私钥解密..."); //Cipher.DECRYPT_MODE意思是解密模式,从一对钥匙中得到私钥 key.getPrivate() cipher.init(Cipher.DECRYPT_MODE, key.getPrivate()); //用私钥进行解密,返回一个字节流 byte[] newPlainText = cipher.doFinal(cipherText); String after2 = new String(newPlainText, "UTF8"); System.out.println("用私钥解密完成:"+after2);
##4. 數位簽章
/** * 此例子是数字签名的例子,使用RSA私钥对消息摘要(这里指的是原始数据)进行签名,然后使用公钥验证签名 * * A通过使用B的公钥加密数据后发给B,B利用B的私钥解密就得到了需要的数据(进过B公钥加密的数据只有B的私钥能够 * 解开,C没有B的私钥,所以C解不开,但C可以使用B的公钥加密一份数据发给B,这样一来,问题来了,B收到的数据到 * 底是A发过来的还是C发过来的呢) * 由于私钥是唯一的,那么A就可以利用A自己的私钥进行加密,然后B再利用A的公钥来解密,就可以确定:一定是A的消 * 息,数字签名的原理就基于此 * * 总结:A想将目标数据传给B,此时A需要准备1和2两部分 * 1:A使用B的公钥将原始信息加密,以起到保密作用(只有B的私钥能解开,其他人使用其他钥匙都解不开,当然就保密咯) * 2:A使用A的私钥将原始信息的摘要进行签名,以起到接收方B确定是A发过来的作用(A用A的私钥对目标数据的摘要进行签 * 名,然后传给B,同时,C用C的私钥对任意信息进行签名也传给B,B想接受的是A的数据(比如说一个转帐请求),于是B * 就通过A的公钥对接受到的两个信息进行解密,解开的就是A(A的公钥能且只能解开A的私钥加密的数据)) */ String before = "asdf"; byte[] plainText = before.getBytes("UTF8"); //形成RSA公钥对 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024); KeyPair key = keyGen.generateKeyPair(); //使用私钥签名********************************************************** Signature sig = Signature.getInstance("SHA1WithRSA"); sig.initSign(key.getPrivate()); //sig对象得到私钥 //签名对象得到原始数据 sig.update(plainText); //sig对象得到原始数据(现实中用的是原始数据的摘要,摘要的是单向的,即摘要算法后无法解密) byte[] signature = sig.sign(); //sig对象用私钥对原始数据进行签名,签名后得到签名signature em.out.println(sig.getProvider().getInfo()); String after1 = new String(signature, "UTF8"); System.out.println("/n用私钥签名后:"+after1); //使用公钥验证 sig.initVerify(key.getPublic()); //sig对象得到公钥 //签名对象得到原始信息 sig.update(plainText); //sig对象得到原始数据(现实中是摘要) try { if (sig.verify(signature)) { //sig对象用公钥解密签名signature得到原始数据(即摘要),一致则true System.out.println("签名验证正确!!"+new String(plainText, "UTF8")); } else { System.out.println("签名验证失败!!"); } } catch (SignatureException e) { System.out.println("签名验证失败!!"); }
#5. 數位憑證
/** * 此例是对“数字证书”文件的操作 * java平台(在机器上安装jdk)为你提供了密钥库(证书库),cmd下提供了keytool命令就可以创建证书库 * * 在运行此例前: * 在c盘目录下创建一个证书,指定证书库为BocsoftKeyLib,创建别名为TestCertification的一条证书,它指定用 * RSA 算法生成,且指定密钥长度为1024,证书有效期为1年 * 导出证书文件为TC.cer已存于本地磁盘C:/ * 密码是qazzaq */ try { //前提:将证书库中的一条证书导出到证书文件(我写的例子里证书文件叫TC.cer) //从证书文件TC.cer里读取证书信息 CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream in = new FileInputStream("C:/TC.cer"); //将文件以文件流的形式读入证书类Certificate中 Certificate c = cf.generateCertificate(in); System.err.println("转换成String后的证书信息:"+c.toString()); */ //或者不用上面代码的方法,直接从证书库中读取证书信息,和上面的结果一摸一样 String pass="qazzaq"; FileInputStream in2=new FileInputStream("C:/BocsoftKeyLib"); KeyStore ks=KeyStore.getInstance("JKS"); ks.load(in2,pass.toCharArray()); String alias = "TestCertification"; //alias为条目的别名 Certificate c=ks.getCertificate(alias); System.err.println("转换成String后的证书信息:"+c.toString()); //获取获取X509Certificate类型的对象,这是证书类获取Certificate的子类,实现了更多方法 X509Certificate t=(X509Certificate)c; //从信息中提取需要信息 System.out.println("版本号:"+t.getVersion()); System.out.println("序列号:"+t.getSerialNumber().toString(16)); System.out.println("主体名:"+t.getSubjectDN()); System.out.println("签发者:"+t.getIssuerDN()); System.out.println("有效期:"+t.getNotBefore()); System.out.println("签名算法:"+t.getSigAlgName()); byte [] sig=t.getSignature(); //签名值 PublicKey pk = t.getPublicKey(); byte [] pkenc=pk.getEncoded(); System.out.println("公钥:"); for (int i=0;i<pkenc.length;i++){ System.out.print(pkenc[i]+","); } System.err.println(); //证书的日期有效性检查,颁发的证书都有一个有效性的日期区间 Date TimeNow=new Date(); t.checkValidity(TimeNow); System.out.println("证书的日期有效性检查:有效的证书日期!"); //验证证书签名的有效性,通过数字证书认证中心(CA)机构颁布给客户的CA证书,比如:caroot.crt文件 //我手里没有CA颁给我的证书,所以下面代码执行不了 /*FileInputStream in3=new FileInputStream("caroot.crt"); //获取CA证书 Certificate cac = cf.generateCertificate(in3); //获取CA的公钥 PublicKey pbk=cac.getPublicKey(); //c为本地证书,也就是待检验的证书,用CA的公钥校验数字证书c的有效性 c.verify(pbk); } catch(CertificateExpiredException e){//证书的日期有效性检查:过期 System.out.println("证书的日期有效性检查:过期"); } catch(CertificateNotYetValidException e){ //证书的日期有效性检查:尚未生效 System.out.println("证书的日期有效性检查:尚未生效"); } catch (CertificateException ce) { ce.printStackTrace(); } catch (FileNotFoundException fe) { fe.printStackTrace(); } /*catch (IOException ioe){ } catch (KeyStoreException kse){ }*/ catch (Exception e){ e.printStackTrace(); } }
以上內容就是關於Java加密解密和數位簽章完整程式碼範例的全部內容,覺得不錯的趕緊收藏起來吧。 相關推薦:
mysql關於加密解密的函數#Java中DES加密解密工具類別的實作實例php加密解密的幾種方法的使用教學以上是Java加密解密與數位簽章完整程式碼範例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

Java的平台獨立性是指編寫的代碼可以在任何安裝了JVM的平台上運行,無需修改。 1)Java源代碼編譯成字節碼,2)字節碼由JVM解釋執行,3)JVM提供內存管理和垃圾回收功能,確保程序在不同操作系統上運行。

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

云计算显著提升了Java的平台独立性。1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技術如Docker增強而非替代Java的平台獨立性。 1)確保跨環境的一致性,2)管理依賴性,包括特定JVM版本,3)簡化部署過程,使Java應用更具適應性和易管理性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 Linux新版
SublimeText3 Linux最新版