JAVA文本文档的加密与解密
JAVA实现古典置换密码的加密解密
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;public class zhihuan {public static void main(String args[]) throws IOException{System.out.println("请您输入需要的服务,1为加密,2为解密");BufferedReader br=new BufferedReader(new InputStreamReader(System.in));int Choice=Integer.parseInt(br.readLine());if(Choice==1){System.out.println("您进入了加密程序");System.out.print("请输入您需要加密的明文:");String MingWen=br.readLine();System.out.print("请输入加密秘钥:");String key=br.readLine();jiami(MingWen,key);Choice=2;}if(Choice==2){System.out.println("您进入了解密程序");System.out.print("请输入您需要解密的密文:");String MiWen=br.readLine();System.out.print("请输入解密秘钥:");String key2=br.readLine();jiemi(MiWen,key2);System.exit(0);}else{System.out.println("输入错误,请重新输入,1为加密,2为解密:\n");System.exit(0);}}static void jiami(String mingwen,String key){int hang=(int)Math.ceil((double)mingwen.length()/(double)key.length());//行数int lie=key.length();//列数char[][] juzhen=new char[hang][lie];//定义矩阵存储明文int temp=0;for(int i=0;i<hang;i++)//嵌套循环将明文存入矩阵{for(int j=0;j<lie;j++){if(temp<mingwen.length()){juzhen[i][j]=mingwen.charAt(temp);temp++;}}}int[] key_xu=new int[key.length()];//此数组存储秘钥字母顺序for(int i=0;i<key.length();i++)//将秘钥转ASCII码{key_xu[i]=(int)key.charAt(i);}Arrays.sort(key_xu); //对秘钥ASCII码进行排序int[] a=new int[key.length()];//此数组用于记录转换映射for(int i=0;i<key.length();i++)//利用嵌套循环在数组a中记录转换映射关系for(int j=0;j<key.length();j++){if( (int)key.charAt(i)==key_xu[j]){a[i]=j;}}char[][] mima=new char[hang][lie];//定义第一次转置后的密码矩阵for(int j=0;j<lie;j++)//开始第一次转置for(int i=0;i<hang;i++){mima[i][j]=juzhen[i][a[j]];}System.out.print("加密后密码:");for(int j=0;j<lie;j++)//第二次转置输出结果{for(int i=0;i<hang;i++){System.out.print(mima[i][a[j]]);}}}static void jiemi(String miwen,String key){int hang=(int)Math.ceil((double)miwen.length()/(double)key.length());//int lie=key.length();//char[][] juzhen=new char[hang][lie];int temp=0;for(int j=0;j<lie;j++)//嵌套循环将明文存入矩阵{for(int i=0;i<hang;i++){if(temp<miwen.length()){juzhen[i][j]=miwen.charAt(temp);temp++;}}}int[] key_xu=new int[key.length()];//此数组存储秘钥字母顺序for(int i=0;i<key.length();i++)//将秘钥转ASCII码{key_xu[i]=(int)key.charAt(i);}Arrays.sort(key_xu); //对秘钥ASCII码进行排序int[] a=new int[key.length()];//此数组用于记录转换映射for(int i=0;i<key.length();i++)//利用嵌套循环在数组a中记录转换映射关系for(int j=0;j<key.length();j++){if( (int)key.charAt(i)==key_xu[j]){a[i]=j;}}char[][] ming=new char[hang][lie];//定义第一次转置后的密码矩阵for(int j=0;j<lie;j++)//开始第一次转置for(int i=0;i<hang;i++){ming[i][a[j]]=juzhen[i][j];}char[][] mingwen=new char[hang][lie];for(int j=0;j<lie;j++)//开始第2次转置for(int i=0;i<hang;i++){mingwen[i][a[j]]=ming[i][j];}System.out.println("解密结果为:");for(int i=0;i<hang;i++){for(int j=0;j<lie;j++){System.out.print(mingwen[i][j]);}}}}。
SpringBoot中_JAVA利用国密算法_实现内容的加密_解密
首先来看一下什么是国密算法:国密即国家密码局认定的国产密码算法,即商用密码。
国密主要有SM1,SM2,SM3,SM4。
密钥长度和分组长度均为128位。
1、SM1 为对称加密。
其加密强度与AES(高级加密标准,Advanced Encryption Standard)相当。
该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
2、SM2为非对称加密,基于ECC。
该算法已公开。
由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。
ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
3、SM3为消息摘要。
可以用MD5作为对比理解。
该算法已公开。
校验结果为256位。
4、SM4为无线局域网标准的分组数据算法。
对称加密,密钥长度和分组长度均为128位。
由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。
在很多地方还是会用到的,这里说一下这个:SM21.在pom.xml中引入依赖jar包:<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.58</version></dependency>2.然后来写一个工具类,用来生成国密的,公钥和私钥这个密码对.import org.bouncycastle.jce.provider.BouncyCastleProvider;import java.security.*;import java.security.spec.ECGenParameterSpec;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Base64;/*** @author hulala* @Description 国密公私钥对工具类public class KeyUtils {/*** 生成国密公私钥对** @return* @throws Exception*/public static String[] generateSmKey() throws Exception {KeyPairGenerator keyPairGenerator = null;SecureRandom secureRandom = new SecureRandom();ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");keyPairGenerator = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());keyPairGenerator.initialize(sm2Spec);keyPairGenerator.initialize(sm2Spec, secureRandom);KeyPair keyPair = keyPairGenerator.generateKeyPair();PrivateKey privateKey = keyPair.getPrivate();PublicKey publicKey = keyPair.getPublic();//String[0] 公钥//String[1] 私钥String[] result = {new String(Base64.getEncoder().encode(publicKey.getEncoded())), new String(Base64.getEncoder().encode(privateKey.getEncoded())) };return result;}/*** 将Base64转码的公钥串,转化为公钥对象** @param publicKey* @return*/public static PublicKey createPublicKey(String publicKey) {PublicKey publickey = null;try {X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());publickey = keyFactory.generatePublic(publicKeySpec);} catch (Exception e) {e.printStackTrace();}return publickey;}/*** 将Base64转码的私钥串,转化为私钥对象** @param privateKey* @return*/public static PrivateKey createPrivateKey(String privateKey) {PrivateKey publickey = null;try {PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());publickey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);} catch (Exception e) {e.printStackTrace();}return publickey;}}3.根据公钥和私钥工具类,生成的密钥对,对数据,进行加密和解密操作import org.bouncycastle.asn1.gm.GMObjectIdentifiers;import org.bouncycastle.crypto.InvalidCipherTextException;import org.bouncycastle.crypto.engines.SM2Engine;import org.bouncycastle.crypto.params.ECDomainParameters;import org.bouncycastle.crypto.params.ECPrivateKeyParameters;import org.bouncycastle.crypto.params.ECPublicKeyParameters;import org.bouncycastle.crypto.params.ParametersWithRandom;import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.jce.spec.ECParameterSpec;import java.security.*;/*** @author hulala* @Description SM2实现工具类*/public class Sm2Util {static {Security.addProvider(new BouncyCastleProvider());}/*** 根据publicKey对原始数据data,使用SM2加密** @param data* @param publicKey* @return*/public static byte[] encrypt(byte[] data, PublicKey publicKey) {ECPublicKeyParameters localECPublicKeyParameters = null;if (publicKey instanceof BCECPublicKey) {BCECPublicKey localECPublicKey = (BCECPublicKey) publicKey;ECParameterSpec localECParameterSpec = localECPublicKey.getParameters();ECDomainParameters localECDomainParameters = new ECDomainParameters(localECParameterSpec.getCurve(),localECParameterSpec.getG(), localECParameterSpec.getN());localECPublicKeyParameters = new ECPublicKeyParameters(localECPublicKey.getQ(), localECDomainParameters);}SM2Engine localSM2Engine = new SM2Engine();localSM2Engine.init(true, new ParametersWithRandom(localECPublicKeyParameters, new SecureRandom()));byte[] arrayOfByte2;try {arrayOfByte2 = localSM2Engine.processBlock(data, 0, data.length);return arrayOfByte2;} catch (InvalidCipherTextException e) {e.printStackTrace();return null;}}/*** 根据privateKey对加密数据encodedata,使用SM2解密** @param encodedata* @param privateKey* @return*/public static byte[] decrypt(byte[] encodedata, PrivateKey privateKey) {SM2Engine localSM2Engine = new SM2Engine();BCECPrivateKey sm2PriK = (BCECPrivateKey) privateKey;ECParameterSpec localECParameterSpec = sm2PriK.getParameters();ECDomainParameters localECDomainParameters = new ECDomainParameters(localECParameterSpec.getCurve(),localECParameterSpec.getG(), localECParameterSpec.getN());ECPrivateKeyParameters localECPrivateKeyParameters = new ECPrivateKeyParameters(sm2PriK.getD(),localECDomainParameters);localSM2Engine.init(false, localECPrivateKeyParameters);try {byte[] arrayOfByte3 = localSM2Engine.processBlock(encodedata, 0, encodedata.length);return arrayOfByte3;} catch (InvalidCipherTextException e) {e.printStackTrace();return null;}}/*** 私钥签名** @param data* @param privateKey* @return* @throws Exception*/public static byte[] signByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception { Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(privateKey);sig.update(data);byte[] ret = sig.sign();return ret;}/*** 公钥验签** @param data* @param publicKey* @param signature* @return* @throws Exception*/public static boolean verifyByPublicKey(byte[] data, PublicKey publicKey, byte[] signature) throws Exception {Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initVerify(publicKey);sig.update(data);boolean ret = sig.verify(signature);return ret;}}4.来测试一下,对数据进行加密解密import org.junit.Test;import java.util.Base64;/*** @author hulala* @Description Sm2Util 的测试类*/public class Sm2UtilTest {private String testStr = "wangjing";java.security.PublicKey publicKey = null;java.security.PrivateKey privateKey = null;@Testpublic void test() throws Exception {//生成公私钥对String[] keys = KeyUtils.generateSmKey();System.out.println("原始字符串:" + testStr);System.out.println("公钥:" + keys[0]);publicKey = KeyUtils.createPublicKey(keys[0]);System.out.println("私钥:" + keys[1]);privateKey = KeyUtils.createPrivateKey(keys[1]);System.out.println("");byte[] encrypt = Sm2Util.encrypt(testStr.getBytes(), publicKey);String encryptBase64Str = Base64.getEncoder().encodeToString(encrypt);System.out.println("加密数据:" + encryptBase64Str);byte[] decode = Base64.getDecoder().decode(encryptBase64Str);byte[] decrypt = Sm2Util.decrypt(decode, privateKey);System.out.println("解密数据:" + new String(decrypt));byte[] sign = Sm2Util.signByPrivateKey(testStr.getBytes(), privateKey);System.out.println("数据签名:" + Base64.getEncoder().encodeToString(sign));boolean b = Sm2Util.verifyByPublicKey(testStr.getBytes(), publicKey, sign);System.out.println("数据验签:" + b);}}5.这样就实现了利用国密,SM2进行加密解密了.。
C#与JavaRsa加密与解密互通
C#与JavaRsa加密与解密互通Rsa 加密标准的制定已经过去了⼗多年了. 这两天在看rsa 加密的⽂章,基本上都是在说 .net 与 java 之间的 rsa加密是不能互通的.因为项⽬有⽤到,所以花了点时间对rsa加密做了⼀点点了解,发现,不管是java 还是 C# 都对 rsa 的标准加密进⾏了实现, 是对于标准是实现,不能互通就讲不过去了. 今天特意写了⼀段java 代码试了⼀下,发现是完全可以的.密钥的描述: C#(.net) 中有三种⽅式导出密钥,⼀种是blob,⼀种是 xml 另⼀种是参数,其中xml 的⽅式是把参数进⾏了 xml序列化.blob 的形式我没看懂是什么意思,只知道⽂档上说是给微软的什么api⽤的,下⾯给出其参数的形式.RSAParameters 字段Contains对应的 PKCS #1 字段d,私钥指数privateExponentd mod (p - 1) exponent1d mod (q - 1) exponent2e,公钥指数publicExponent(InverseQ)(q) = 1 mod p coefficientn modulusp prime1q prime2RSA 算法若要⽣成密钥对,可以从创建名为 p 和 q 的两个⼤的质数开始; 这两个数相乘,结果称为 n; 因为 p 和 q 都是质数,所以 n 的全部因数为 1、p、q 和 n;如果仅考虑⼩于 n 的数,则与 n 为互质数(即与 n 没有公因数)的数的个数等于 (p - 1)(q - 1);现在,选择⼀个数 e,它与计算的值为互质数; 则公钥表⽰为 {e, n};若要创建私钥,则必须计算 d,它是满⾜ (d)(e) mod n = 1 的⼀个数; 根据 Euclidean 算法,私钥为 {d, n};纯⽂本 m 到密码⽂本 c 的加密定义为 c = (m ^ e) mod n; 解密则定义为 m = (c ^ d) mod n;总之,我们可以从 .net 的rsa 中拿到合适的密钥描述就是了,⾄于 java的,我想也是可以做到的,⽽且通常密钥是应该放在密钥容器的.接下来我们⽤.net ⽣成⼀个 rsa 的密钥,以⼗六进制的⽅式输出的(new ⼀个RSACryptoServiceProvider,把密钥导出就可以了)D: 2FE7479CF4CFEE63218C44D763C3E552DC5FBC94A31F944B88AE8E58F0ED16874B8BED35307B143F413761B2ECFFC95F48DF0D0A29FC155C0B968EFE9FFF36E7DP: 6777B761BC29637622FC63682243BB2E05CCFC6FF710ADE1DCE6B0C843B17C4FDQ: 68771CCDA40F0DA0B504C438BB03F7DF30F77364094D475E70270D148260D247Exponent: 010001InverseQ: 5665AB47697008CC2CECB544B582B9C50628281C400846C1E736629B03FE5C85Modulus: B3F276C8EDF515FD3248CCF4163480B9F77443A666522D66B89411EC6DFE11DEA917A97C977750EE777DACBD4D2C11BC363FDC110E5CCA0A1361D51AFA4A7ADDP: ECC60A01B1BDCBA1C5422D8A0A34FC0E46727DB4ED5089E54C356F052E0AB573Q: C28F233948483D0CD0E3FA7B5D2955F2B15E831B38876FB0E7180D873EDF7A6F为了⽅便写.net 代码,这⾥贴⼀下blob的密钥0702000000A40000525341320002000001000100DD7A4AFA1AD561130ACA5C0E11DC3F36BC112C4DBDAC7D77EE5077977CA917A9DE11FE6DEC1194B8662D5266A64374F7B9803416F4CC4832FD15F5EDC876F2B373B50A2E056F354CE58因为是私钥,所以同时可以加密和解密.下⾯上 C# 代码,⽐较简单using System;using System.Security.Cryptography;class Program{public static void Main(string[] args){byte[] plainText = new byte[]{0,1,2,3,4,5};byte[] cipherText;byte[] key = String2Bytes("0702000000A40000525341328001000001000100D3D10816051881319774576B67B1D24F3AA303471A4402AB625208EC1CB04D508AF2098227C5EE185890ECB83E6971C12BDCF4F8AB0FD729167C815D34 using(var rsa = new RSACryptoServiceProvider()){rsa.ImportCspBlob(key);Console.WriteLine("OAEP:");Console.WriteLine(Bytes2String(rsa.Encrypt(plainText, true)));Console.WriteLine("PCSK1-v1_5:");Console.WriteLine(Bytes2String(rsa.Encrypt(plainText, false)));}Console.Write("Press any key to continue . . . ");Console.ReadKey(true);}const string pattern = @"[^0-9a-fA-F]+";static byte[] String2Bytes(string str){str = System.Text.RegularExpressions.Regex.Replace(str, pattern, "");if (str == string.Empty)return null;byte[] data = new byte[str.Length / 2];for (int i = 0; i < data.Length; ++i)data[i] = byte.Parse(str.Substring(2 * i, 2), System.Globalization.NumberStyles.HexNumber);return data;}static string Bytes2String(byte[] data){System.Text.StringBuilder builder = new System.Text.StringBuilder();foreach (var element in data) {builder.AppendFormat("{0:X2}",element);}return builder.ToString();}}运⾏后输出(rsa加密,密⽂每次都不⼀定⼀样):OAEP:87F04B0F28B81D23E63DA71C8278E0B7E357F40583BDDCAB493D44A58080EB178EC8E0DB0DCD4BE5427FDB8190229B8DF2511BDA1082607C92BD03B0615D5AD3 PCSK1-v1_5:358AB4D336D0C35DAE3895E8A125F4F5AD0FB58117A4100FAF15DE95FF8615F01FFB1A59C9B579792B7C14E93E54A3E7E236D464DDB93D8DF9D96F63F46BACD7现在我们有密⽂了,⾄于.net 的解密 .net 加密后的密⽂,我没兴趣去看,反正铁定可以的就是了.下⾯我们写java 的解密部分package rsatest;import java.math.BigInteger;import java.security.KeyFactory;import java.security.PrivateKey;import java.security.PublicKey;import java.security.spec.RSAPrivateKeySpec;import java.security.spec.RSAPublicKeySpec;import javax.crypto.Cipher;public class RsaTest {public static void main(String[] args) throws Exception {//前⾯补了个0,符号位为0,表⽰⾮负BigInteger n = new BigInteger("B3F276C8EDF515FD3248CCF4163480B9F77443A666522D66B89411EC6DFE11DEA917A97C977750EE777DACBD4D2C11BC363FDC110E5CCA0A1361D51AFA4A7ADD", 16); BigInteger e = new BigInteger("010001", 16);BigInteger d = new BigInteger("2FE7479CF4CFEE63218C44D763C3E552DC5FBC94A31F944B88AE8E58F0ED16874B8BED35307B143F413761B2ECFFC95F48DF0D0A29FC155C0B968EFE9FFF36E7", 16);RSAPublicKeySpec keySpec = new RSAPublicKeySpec(n, e);PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);RSAPrivateKeySpec prvKeySpec = new RSAPrivateKeySpec(n, d);PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(prvKeySpec);//现在key 准备好了,把前⾯的密⽂放这⾥解密byte[] oaepCiphertext = Hex2Bytes("87F04B0F28B81D23E63DA71C8278E0B7E357F40583BDDCAB493D44A58080EB178EC8E0DB0DCD4BE5427FDB8190229B8DF2511BDA1082607C92BD03B0615D5AD3");//解密OAEP 加密的数据Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] plaintext = cipher.doFinal(oaepCiphertext);System.out.println(Bytes2Hex(plaintext));//解密PKCS1-v1_5 加密的数据byte[] ciphertext = Hex2Bytes("358AB4D336D0C35DAE3895E8A125F4F5AD0FB58117A4100FAF15DE95FF8615F01FFB1A59C9B579792B7C14E93E54A3E7E236D464DDB93D8DF9D96F63F46BACD7");cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);plaintext = cipher.doFinal(ciphertext);System.out.println(Bytes2Hex(plaintext));}public static byte[] Hex2Bytes(String hexStr) {if (hexStr.length() % 2 != 0) {hexStr = "0" + hexStr;}byte[] bytes = new byte[hexStr.length() / 2];for (int i = 0; i < bytes.length; ++i) {bytes[i] = (byte) Integer.parseUnsignedInt(hexStr.substring(i * 2, i * 2 + 2), 16);}return bytes;}public static String Bytes2Hex(byte[] bytes) {StringBuilder builder = new StringBuilder();for (byte b : bytes) {builder.append(String.format("%02X", b));}return builder.toString();}}程序运⾏后输出:000102030405000102030405跟我们预期的是⼀样的.我们再⽤java 对明⽂加密,代码⽚段// plaintext {0,1,2,3,4,5}cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");cipher.init(Cipher.ENCRYPT_MODE, publicKey);oaepCiphertext = cipher.doFinal(plaintext);System.out.println("OAEP:");System.out.println(Bytes2Hex(oaepCiphertext));cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);ciphertext = cipher.doFinal(plaintext);System.out.println("PCSK1-v1_5:");System.out.println(Bytes2Hex(ciphertext));对应输出(rsa加密,密⽂每次都不⼀定⼀样):OAEP:3144C4CB06C7F49D31E65D09C840069F7CCF602487908CCEAB33D473B949199E1795530B69E1FA20EB59E392B2B934024D46E979DEA1682BDFA61D6FDD980F9C PCSK1-v1_5:699A694BEB75616879C6B8D311CC10D987EA109D494EE6C9380CD2C02A124613F130C440CB1CA6D3405E50B62CF96A79EB43C3370253E5D8C1A9132CFE01D686接下来⽤C# 对数据解密,代码⽚段//还是⽤之前那个rsa对象//OAEPcipherText = String2Bytes("3144C4CB06C7F49D31E65D09C840069F7CCF602487908CCEAB33D473B949199E1795530B69E1FA20EB59E392B2B934024D46E979DEA1682BDFA61D6FDD980F9C"); Console.WriteLine(Bytes2String(rsa.Decrypt(cipherText, true)));//PCSK1-v1_5cipherText = String2Bytes("699A694BEB75616879C6B8D311CC10D987EA109D494EE6C9380CD2C02A124613F130C440CB1CA6D3405E50B62CF96A79EB43C3370253E5D8C1A9132CFE01D686"); Console.WriteLine(Bytes2String(rsa.Decrypt(cipherText, false)));对应的输出:000102030405000102030405解密也成功了.或许该头疼的问题是,已知 {e,n} 或者 {d,n} 怎么⽣成.net 使⽤的密钥.。
Java实现MD5加密及解密的代码实例分享
Java实现MD5加密及解密的代码实例分享基础:MessageDigest类的使⽤其实要在Java中完成MD5加密,MessageDigest类⼤部分都帮你实现好了,⼏⾏代码⾜矣:/*** 对字符串md5加密** @param str* @return*/import java.security.MessageDigest;public static String getMD5(String str) {try {// ⽣成⼀个MD5加密计算摘要MessageDigest md = MessageDigest.getInstance("MD5");// 计算md5函数md.update(str.getBytes());// digest()最后确定返回md5 hash值,返回值为8为字符串。
因为md5 hash值是16位的hex值,实际上就是8位的字符// BigInteger函数则将8位的字符串转换成16位hex值,⽤字符串来表⽰;得到字符串形式的hash值return new BigInteger(1, md.digest()).toString(16);} catch (Exception e) {throw new SpeedException("MD5加密出现错误");}}进阶:加密及解密类Java实现MD5加密以及解密类,附带测试类,具体见代码。
MD5加密解密类——MyMD5Util,代码如下package com.zyg.security.md5;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.util.Arrays;public class MyMD5Util {private static final String HEX_NUMS_STR="0123456789ABCDEF";private static final Integer SALT_LENGTH = 12;/*** 将16进制字符串转换成字节数组* @param hex* @return*/public static byte[] hexStringToByte(String hex) {int len = (hex.length() / 2);byte[] result = new byte[len];char[] hexChars = hex.toCharArray();for (int i = 0; i < len; i++) {int pos = i * 2;result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4| HEX_NUMS_STR.indexOf(hexChars[pos + 1]));}return result;}/*** 将指定byte数组转换成16进制字符串* @param b* @return*/public static String byteToHexString(byte[] b) {StringBuffer hexString = new StringBuffer();for (int i = 0; i < b.length; i++) {String hex = Integer.toHexString(b[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}hexString.append(hex.toUpperCase());}return hexString.toString();}/*** 验证⼝令是否合法* @param password* @param passwordInDb* @return* @throws NoSuchAlgorithmException* @throws UnsupportedEncodingException*/public static boolean validPassword(String password, String passwordInDb)throws NoSuchAlgorithmException, UnsupportedEncodingException {//将16进制字符串格式⼝令转换成字节数组byte[] pwdInDb = hexStringToByte(passwordInDb);//声明盐变量byte[] salt = new byte[SALT_LENGTH];//将盐从数据库中保存的⼝令字节数组中提取出来System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH);//创建消息摘要对象MessageDigest md = MessageDigest.getInstance("MD5");//将盐数据传⼊消息摘要对象md.update(salt);//将⼝令的数据传给消息摘要对象md.update(password.getBytes("UTF-8"));//⽣成输⼊⼝令的消息摘要byte[] digest = md.digest();//声明⼀个保存数据库中⼝令消息摘要的变量byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH];//取得数据库中⼝令的消息摘要System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length); //⽐较根据输⼊⼝令⽣成的消息摘要和数据库中消息摘要是否相同if (Arrays.equals(digest, digestInDb)) {//⼝令正确返回⼝令匹配消息return true;} else {//⼝令不正确返回⼝令不匹配消息return false;}}/*** 获得加密后的16进制形式⼝令* @param password* @return* @throws NoSuchAlgorithmException* @throws UnsupportedEncodingException*/public static String getEncryptedPwd(String password)throws NoSuchAlgorithmException, UnsupportedEncodingException {//声明加密后的⼝令数组变量byte[] pwd = null;//随机数⽣成器SecureRandom random = new SecureRandom();//声明盐数组变量byte[] salt = new byte[SALT_LENGTH];//将随机数放⼊盐变量中random.nextBytes(salt);//声明消息摘要对象MessageDigest md = null;//创建消息摘要md = MessageDigest.getInstance("MD5");//将盐数据传⼊消息摘要对象md.update(salt);//将⼝令的数据传给消息摘要对象md.update(password.getBytes("UTF-8"));//获得消息摘要的字节数组byte[] digest = md.digest();//因为要在⼝令的字节数组中存放盐,所以加上盐的字节长度pwd = new byte[digest.length + SALT_LENGTH];//将盐的字节拷贝到⽣成的加密⼝令字节数组的前12个字节,以便在验证⼝令时取出盐 System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);//将消息摘要拷贝到加密⼝令字节数组从第13个字节开始的字节System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);//将字节数组格式加密后的⼝令转化为16进制字符串格式的⼝令return byteToHexString(pwd);}}测试类——Client,代码如下:package com.zyg.security.md5;import java.io.UnsupportedEncodingException;import java.security.NoSuchAlgorithmException;import java.util.HashMap;import java.util.Map;public class Client {private static Map users = new HashMap();public static void main(String[] args){String userName = "zyg";String password = "123";registerUser(userName,password);userName = "changong";password = "456";registerUser(userName,password);String loginUserId = "zyg";String pwd = "1232";try {if(loginValid(loginUserId,pwd)){System.out.println("欢迎登陆");}else{System.out.println("⼝令错误,请重新输⼊");}} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 注册⽤户** @param userName* @param password*/public static void registerUser(String userName,String password){String encryptedPwd = null;try {encryptedPwd = MyMD5Util.getEncryptedPwd(password);users.put(userName, encryptedPwd);} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 验证登陆** @param userName* @param password* @return* @throws UnsupportedEncodingException* @throws NoSuchAlgorithmException*/public static boolean loginValid(String userName,String password)throws NoSuchAlgorithmException, UnsupportedEncodingException{String pwdInDb = (String)users.get(userName);if(null!=pwdInDb){ // 该⽤户存在return MyMD5Util.validPassword(password, pwdInDb);}else{System.out.println("不存在该⽤户");return false;}}}PS:这⾥再为⼤家提供2款MD5加密⼯具,感兴趣的朋友可以参考⼀下:MD5在线加密⼯具:在线MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密⼯具:。
java 文件锁 用法
java 文件锁用法Java 文件锁(File Lock)的用法引言:在Java编程中,文件锁(File Lock)是一种机制,用于控制对文件的并发访问,以避免多个线程或进程同时对同一个文件进行读写操作而引发的数据竞争和不一致问题。
它可以确保在一个时间点只有一个线程或进程可以对文件进行访问,并且其他线程或进程需要等待直到文件被释放。
本文将介绍Java中文件锁的用法,包括文件锁的基本概念、实现文件锁的不同方法和如何正确使用文件锁来保护文件的并发访问。
一、文件锁的基本概念1. 文件锁的定义文件锁(File Lock)是一种独占锁(Exclusive Lock),它允许一个进程在同一时间内独占地对文件进行读写操作。
当一个进程获取了文件锁后,其他进程将无法获取该锁,直到文件锁被释放。
2. 文件锁的类型Java提供了两种类型的文件锁:共享锁(Shared Lock)和独占锁(Exclusive Lock)。
共享锁允许多个进程同时对文件进行读操作,但不允许写操作;独占锁则只允许一个进程对文件进行读写操作。
在实际应用中,可以根据需要选择使用适合的锁类型。
二、实现文件锁的不同方法1. 使用FileChannel实现文件锁Java的NIO(New IO)库提供了FileChannel类,该类可以用于实现文件锁。
通过FileChannel的lock方法可以获取文件的独占锁或共享锁,使用tryLock方法可以尝试获取锁并返回锁的状态。
示例代码:获取文件的FileChannel对象FileChannel channel = new RandomAccessFile("file.txt", "rw").getChannel();获取文件的独占锁FileLock lock = channel.lock();或者获取文件的共享锁FileLock lock = channel.lock(0, Long.MAX_VALUE, true);尝试获取文件的独占锁,并返回锁的状态FileLock lock = channel.tryLock();2. 使用FileLock接口实现文件锁Java的NIO库还提供了FileLock接口,通过该接口可以实现对文件的锁定和解锁操作。
Java加解密
Java加解密⼀、概述 Jasypt 这个Java类包为开发⼈员提供⼀种简单的⽅式来为项⽬增加加密功能,包括:密码Digest认证,⽂本和对象加密,集成hibernate,Spring Security(Acegi)来增强密码管理。
Jasypt是⼀个Java库,可以使开发者不需太多操作来给Java项⽬添加基本加密功能,⽽且不需要知道加密原理。
根据Jasypt⽂档,该技术可⽤于加密任务与应⽤程序,例如加密密码、敏感信息和数据通信、创建完整检查数据的sums. 其他性能包括⾼安全性、基于标准的加密技术、可同时单向和双向加密的加密密码、⽂本、数字和⼆进制⽂件。
Jasypt也可以与Acegi Security整合也即Spring Security。
Jasypt亦拥有加密应⽤配置的集成功能,⽽且提供⼀个开放的API从⽽任何⼀个Java Cryptography Extension都可以使⽤Jasypt。
Jasypt还符合RSA标准的基于密码的加密,并提供了⽆配置加密⼯具以及新的、⾼可配置标准的加密⼯具。
1、该开源项⽬可⽤于加密任务与应⽤程序,例如加密密码、敏感信息和数据通信 2、还包括⾼安全性、基于标准的加密技术、可同时单向和双向加密的加密密码、⽂本、数字和⼆进制⽂件。
3、Jasypt还符合RSA标准的基于密码的加密,并提供了⽆配置加密⼯具以及新的、⾼可配置标准的加密⼯具。
4、加密属性⽂件(encryptable properties files)、Spring work集成、加密Hibernate数据源配置、新的命令⾏⼯具、URL加密的Apache wicket集成以及升级⽂档。
5、Jasypt也可以与Acegi Security整合也即Spring Security。
Jasypt亦拥有加密应⽤配置的集成功能,⽽且提供⼀个开放的API从⽽任何⼀个Java Cryptography Extension都可以使⽤Jasypt。
Java 加密、解密Word文档
Java加密、解密Word文档对一些重要文档,我们为保证其文档内容不被泄露,常需要对文件进行加密,查看文件时,需要正确输入密码才能打开文件。
下面介绍了一种比较简单的方法给Word文件添加密码保护以及如何给已加密的Word文件取消密码保护。
使用工具:Free Spire.Doc for Java 2.0.0(免费版)Jar文件导入:方法1:通过官网下载控件包。
在程序下新建一个directory目录,并命名(本示例中命名为lib);将控件包lib文件夹下的jar(如下图1)复制到程序中新建的目录下。
复制jar文件后,鼠标右键点击jar文件,选择”Add as Library”。
完成导入(如下图2)。
图1:图2:方法2:通过maven导入。
参考导入方法。
Java代码示例【示例1】设置Word密码保护import com.spire.doc.*;public class Encrypt {public static void main(String[] args){//加载测试文档String input = "test.docx";String output= "result.docx";Document doc = new Document(input);//调用方法加密文档doc.encrypt("123");//保存加密后的文档doc.saveToFile(output);}}文件加密结果:【示例2】取消Word密码保护import com.spire.doc.*;public class Decrypt {public static void main(String[] args){//加载带密码的文件,输入原密码并解除Document doc = new Document();doc.loadFromFile("result.docx",FileFormat.Docx_2013,"123");//将解密后的文档另存doc.saveToFile("Decrypt.docx",FileFormat.Docx_2013);}}运行程序后,生成的文件将不再有密码保护。
java中常用的zip加密方法
文稿:标题:深度探讨Java中常用的Zip加密方法在日常编程开发中,我们经常会遇到对文件进行压缩和加密的需求。
而在Java中,Zip是一种常用的文件压缩格式,而对Zip文件进行加密也是经常需求之一。
本文将从简单到复杂,由浅入深地探讨Java中常用的Zip加密方法,以帮助您全面理解和灵活运用这一技术。
一、基本概念:Zip文件和加密方法在谈论Zip加密方法之前,我们首先来了解一下Zip文件的基本概念以及加密方法的原理。
Zip文件是一种常见的文件压缩格式,它能将多个文件或文件夹打包成一个文件,以减小文件大小,便于传输和存储。
而加密则是通过对文件内容进行转换或者使用密码算法,以使文件内容对他人不可读或不可用。
二、Zip加密的基本用法在Java中,可以使用`java.util.zip`包中的`ZipOutputStream`和`ZipEntry`类来对文件进行压缩,同时也可以通过密码来对Zip文件进行加密和解密。
通过简单的示例代码,我们可以很容易地了解到如何使用Java对Zip文件进行加密和解密的基本用法。
三、常见的Zip加密方法除了基本用法之外,Java中还提供了一些常见的Zip加密方法,如使用密码对Zip文件进行加密、使用AES算法对Zip文件进行加密等。
这些方法各自有着不同的特点和适用场景,我们可以根据需求选择最合适的方法来进行实现。
四、实践操作:示例演练在本节中,我们将结合实际的示例演练来对之前所学习到的Zip加密方法进行实际操作。
通过实际的演练,我们可以更加深入地理解和掌握这些方法的具体细节和注意事项。
五、个人观点和总结在本节中,我将共享我的个人观点和理解,以及对Zip加密方法在实际开发中的应用和注意事项进行总结和回顾。
通过对Zip加密方法的全面评估和实际应用,我们可以更好地掌握这一技术,并在实际项目中灵活运用。
结语通过本文的深度探讨和示例演练,我相信您已经对Java中常用的Zip 加密方法有了更深入的理解和掌握。
Java使用数字证书加密文件(含代码)
JA V A 使用数字证书加密解密文件总结目录1.编写目的 (3)2.JA V A生产数字证书 (4)2.1.1 keystore(JKS) 的生成 (4)2.1.2 导出公钥 (5)3.使用JKS私钥加密文件 (5)4.转换为PFX格式私钥 (6)5.使用PFX加密文件 (7)6 源代码 (8)6.1 用到的JAR包 (8)6.2 示例代码 (8)6.2.1 Test.java (8)6.2.2 RsaUtil.java (10)6.2.3 Base64.java (19)7.结束语 (26)1.编写目的学习RSA算法,读取数字证书中的私钥对文件进行加密,使用数字证书的公钥解密,这种方式就是RSA算法.自己对RSA算法的理解:⏹私钥加密公钥解密:如果用私钥对文件加密,发给别人,别人用我公布的公钥进行解密,实现这个文件就是我本人制作的,不是别人做的.⏹公钥加密私钥解密:如果别人用我的公钥加密文件,那么只能我一个人看,只有使用我的私钥进行解密,私钥一定是不能告诉其他人的.本文讲解如何用JKS私钥对文件进行加密,用对于CRT公钥进行解密,将JKS私钥转换为PFX格式私钥,并用PFX私钥对文件进行加密解密Jks:是JA V A的keytools证书工具支持的证书私钥格式pfx:是微软支持的私钥格式⏹2.JAVA生产数字证书为了实现数字证书加密文件,我们首先要制作几个数字证书,如果你已经有了pfx格式的数字证书并且知道其密码,以及对应crt或者cer格式的公钥证书则跳过本章.2.1 keytool 创建数字证书Keytool是一个Java数据证书的管理工具,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里,包含两种数据:⏹密钥实体(Key entity):密钥(secret key)又或者是私钥⏹配对公钥(采用非对称加密):可信任的证书实体(trusted certificate entries),只包含公钥2.1.1 keystore(JKS) 的生成●分阶段生成:命令格式:keytool -genkey -alias yushan(别名) -keypass yushan(别名密码) -keyalg RSA(算法) -keysize 1024(密钥长度) -validity 365(有效期,天单位) -keystore e:\yushan.keystore(指定生成证书的位置和证书名称) -storepass 123456(获取keystore信息的密码);示例:1)cmd下进入java/bin2)输入命令keytool -genkey -alias myalias-keypass 123456-keyalg RSA-keysize 1024 -validity 365 -keystore d: \myalias.keystore -storepass 123456●一次性生成:keytool -genkey -alias yushan -keypass yushan -keyalg RSA -keysize 1024 -validity 365 -keystore e:\yushan.keystore -storepass 123456 -dname "CN=(名字与姓氏), OU=(组织单位名称), O=(组织名称), L=(城市或区域名称), ST=(州或省份名称), C=(单位的两字母国家代码)";(中英文即可)无例图2.1.2 导出公钥命令:keytool -export -alias myalias -keystore d:\myalias.keystore -file d:\myalias.crt -storepass 123456创建结果:3.使用JKS私钥加密文件//工具类RSAUtil rsa = new RSAUtil();//从jks私钥中获取私钥加密串PrivateKey priKeyFromKs = rsa.getPriKeyFromKS("d:\\myalias.keystore","123456", "myalias", "123456");//从jks私钥中获取公钥解密串PublicKey pubKeyFromKS = rsa.getPubKeyFromKS("d:\\myalias.keystore", "123456", "myalias");//从crt公钥中获取公钥解密串PublicKey pubKeyFromCrt = rsa.getPubKeyFromCRT("d:\\myalias.crt");//用私钥串加密rsa.encryptWithPrv("d:\\file.xml",priKeyFromKs,"d:\\file_encWithKSPri.xml", true);//用jks公钥串解密rsa.decryptWithPub("d:\\file_encWithKSPri.xml", pubKeyFromKS, true,"d:\\file_encWithKSPri_decKs.xml");//用crt公钥串解密rsa.decryptWithPub("d:\\file_encWithKSPri.xml", pubKeyFromCrt, true, "d:\\file_encWithKSPri_decCrt.xml");4.转换为PFX格式私钥如果你已经有了pfx格式的数字证书并且知道其密码,以及对应crt或者cer格式的公钥证书则跳过本章.4.1 转换工具转换工具我使用的是kestore-export下载kestore-export.rar 请百度搜索,我也会往CSDN上上传,请直接搜索kestore-export.rar。
java常用加密和解密工具类EncryptUtil.java
java常⽤加密和解密⼯具类EncryptUtil.java 1package cn.util;23import java.io.UnsupportedEncodingException;4import java.security.MessageDigest;5import java.security.NoSuchAlgorithmException;6import java.security.SecureRandom;78import javax.crypto.Cipher;9import javax.crypto.SecretKey;10import javax.crypto.SecretKeyFactory;11import javax.crypto.spec.DESKeySpec;1213/**14 * 加密⼯具类15 *16 * md5加密出来的长度是32位17 *18 * sha加密出来的长度是40位19 *20 * @author伍⽟林21 *22*/23public final class EncryptUtil {2425private static final String PASSWORD_CRYPT_KEY = "88444488";2627private final static String DES = "DES";2829/**30 * ⼆次加密先sha-1加密再⽤MD5加密31 *32 * @param src33 * @return34*/35public final static String md5AndSha(String src) {36return md5(sha(src));37 }3839/**40 * ⼆次加密先MD5加密再⽤sha-1加密41 *42 * @param src43 * @return44*/45public final static String shaAndMd5(String src) {46return sha(md5(src));47 }4849/**50 * md5加密51 *52 * @param src53 * @return54*/55public final static String md5(String src) {56return encrypt(src, "md5");57 }5859/**60 * sha-1加密61 *62 * @param src63 * @return64*/65public final static String sha(String src) {66return encrypt(src, "sha-1");67 }6869/**70 * md5或者sha-1加密71 *72 * @param src73 * 要加密的内容74 * @param algorithmName75 * 加密算法名称:md5或者sha-1,不区分⼤⼩写76 * @return77*/78private final static String encrypt(String src, String algorithmName) {79if (src == null || "".equals(src.trim())) {80throw new IllegalArgumentException("请输⼊要加密的内容");81 }82if (algorithmName == null || "".equals(algorithmName.trim())) {83 algorithmName = "md5";84 }85 String encryptText = null;86try {87 MessageDigest m = MessageDigest.getInstance(algorithmName);88 m.update(src.getBytes("UTF8"));89byte s[] = m.digest();90// m.digest(src.getBytes("UTF8"));91return hex(s);92 } catch (NoSuchAlgorithmException e) {93 e.printStackTrace();94 } catch (UnsupportedEncodingException e) {95 e.printStackTrace();96 }97return encryptText;98 }99100/**101 * 密码解密102 *103 * @param data104 * @return105 * @throws Exception106*/107public final static String decrypt(String src) {108try {109return new String(decrypt(hex2byte(src.getBytes()), PASSWORD_CRYPT_KEY.getBytes())); 110 } catch (Exception e) {111 }112return null;113 }114115/**116 * 密码加密117 *118 * @param password119 * @return120 * @throws Exception121*/122public final static String encrypt(String src) {123try {124return byte2hex(encrypt(src.getBytes(), PASSWORD_CRYPT_KEY.getBytes()));125 } catch (Exception e) {126 }127return null;128 }129130/**131 * 加密132 *133 * @param src134 * 数据源135 * @param key136 * 密钥,长度必须是8的倍数137 * @return返回加密后的数据138 * @throws Exception139*/140private static byte[] encrypt(byte[] src, byte[] key) throws Exception {141// DES算法要求有⼀个可信任的随机数源142 SecureRandom sr = new SecureRandom();143// 从原始密匙数据创建DESKeySpec对象144 DESKeySpec dks = new DESKeySpec(key);145// 创建⼀个密匙⼯⼚,然后⽤它把DESKeySpec转换成⼀个SecretKey对象146 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);147 SecretKey securekey = keyFactory.generateSecret(dks);148// Cipher对象实际完成加密操作149 Cipher cipher = Cipher.getInstance(DES);150// ⽤密匙初始化Cipher对象151 cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);152// 现在,获取数据并加密正式执⾏加密操作153return cipher.doFinal(src);154 }155156/**157 * 解密158 *159 * @param src160 * 数据源161 * @param key162 * 密钥,长度必须是8的倍数163 * @return返回解密后的原始数据164 *165 * @throws Exception166*/167private final static byte[] decrypt(byte[] src, byte[] key) throws Exception {168// DES算法要求有⼀个可信任的随机数源169 SecureRandom sr = new SecureRandom();170// 从原始密匙数据创建⼀个DESKeySpec对象171 DESKeySpec dks = new DESKeySpec(key);172// 创建⼀个密匙⼯⼚,然后⽤它把DESKeySpec对象转换成⼀个SecretKey对象173 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);174 SecretKey securekey = keyFactory.generateSecret(dks);175// Cipher对象实际完成解密操作176 Cipher cipher = Cipher.getInstance(DES);177// ⽤密匙初始化Cipher对象178 cipher.init(Cipher.DECRYPT_MODE, securekey, sr);179// 现在,获取数据并解密正式执⾏解密操作180return cipher.doFinal(src);181 }182183private final static byte[] hex2byte(byte[] b) {184if ((b.length % 2) != 0)185throw new IllegalArgumentException("长度不是偶数");186byte[] b2 = new byte[b.length / 2];187for (int n = 0; n < b.length; n += 2) {188 String item = new String(b, n, 2);189 b2[n / 2] = (byte) Integer.parseInt(item, 16);190 }191return b2;192 }193194/**195 * ⼆⾏制转字符串196 *197 * @param b198 * @return199*/200private final static String byte2hex(byte[] b) {201 String hs = "";202 String stmp = "";203for (int n = 0; n < b.length; n++) {204 stmp = (ng.Integer.toHexString(b[n] & 0XFF));205if (stmp.length() == 1)206 hs = hs + "0" + stmp;207else208 hs = hs + stmp;209 }210return hs.toUpperCase();211 }212213/**214 * 返回⼗六进制字符串215 *216 * @param arr217 * @return218*/219private final static String hex(byte[] arr) {220 StringBuffer sb = new StringBuffer();221for (int i = 0; i < arr.length; ++i) {222 sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1, 3)); 223 }224return sb.toString();225 }226227 }。
