简介
UopenCryptionKit4Java开源库支持AES/DES/3DES/RSA/SM2/SM4/MD5/HmacSHA1/HmacSHA256/SM3等常见的加解密以及签名算法工具,将常见的加密器,加签器统一封装提供操作,并将密码设置和操作过程分离,欢迎大家fork,如果有更好的主意欢迎完善它。
项目地址
https://github.com/fpleihub/UopenCryptionKit4Java.git
目前Kit中支持的加解密器
1.AES
2.DES
3.3DES
4.国密Sm2
5.国密Sm4
6.RSA
目前Kit中支持的签名器
1.DSA
2.HmacSHA1
3.HmacSHA256
4.Md5
5.SM3
快速开始
Maven引用
<dependency> <groupId>io.github.fpleihub</groupId> <artifactId>UopenCryptionKit4Java</artifactId> <version>1.0</version> </dependency>
Gradle引用
implementation 'io.github.fpleihub:UopenCryptionKit4Java:1.0'
DEMO. AES加解密使用
String value = UEncryptionManager.getInstance().withAes("10---323_哈哈四大时刻18211!@", Op.Encryption, ReturnType.TYPE_HEX); System.out.println("AES加密后值:" + value); String value1 = UEncryptionManager.getInstance().withAes(value, Op.Decrypt, ReturnType.TYPE_HEX); System.out.println("AES解密后值:" + value1);
更详细的使用说明
1). 初始化秘钥管理器
工具为了将加密编码过程秘钥和操作分离,单独管理秘钥,避免每次输入或引用,同时统一管理,因此项目使用到了哪些加密器,即继承KeyCreator实现相关的密码源即可,工具内置了一套默认秘钥,如果没有给到工具你的秘钥,那么这可能导致解密失败等情况,(如果想快速体验,可跳过该步骤)
public class MyEncryptKeySource extends KeyCreator { @Override public String getAesPass() { return "my2020aes!@#_121872"; } @Override public String getTriplePass() { return "my2020des$#_!1234567890"; } @Override public String getRsaPrivatePass() { return "xxx"; } @Override public String getRsaPublicPass() { return "xxx"; } @Override public String getHmacShaPass() { return "bilibili1219832020"; } @Override public String getSm2PublicPass() { return "0475658556b7ebff57a95b4da1cfefdb131f22909e2cd3265ace57d67a8033d522d40173db64a78a21d68035148694e01ffd973fb1c1af471c016e59c60c01fc0c"; } @Override public String getSm2PrivatePass() { return "1eadfb948c582c03819d130837de5a6dcb9d8f6101ea1cf05982c27fb75027a5"; } @Override public String getSm4Pass() { return "JeF8U9wHFOMfs2Y8"; } @Override public String getDasPrivateKey() { return "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUBiCZo7Aw+lPTaXf8an2bdqMVCMo="; } @Override public String getDasPublicKey() { return "MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGASIyEgiooFat7lb8fIuTir5JyvxDHBZIbwcvFewZ2eb8Fv7VW+z84CsjNswNOu1f81palcFA8vDyp2bv2tP+3OAAEnWbjYJQDNTc29ZZk3r0SwnPlmlFqLXUmBF8ROce991WEI0khGLwTNlNSMynhLljFZnW1fGplKzWMFetL7DQ="; } }
密码管理器有几个地方需要注意
1)3DES秘钥,长度最好固定24个字符,否则不足将会自动追加补0,或超出会自动截断到24个字符
2)RSA秘钥对可通过/utils/RsaKeyHelper.java生成,内置默认使用Base64字符串作为秘钥串,如果需要更换层数据类型(ReturnType中类型列表),并且调整{RsaPrivateCipher.java/RsaPublicCipher.java}加密器的秘钥编码方式
3)国秘SM2秘钥对可通过/utils/SM2KeyHelper.java}生成,内置默认使用十六进制字符串作为铭文秘钥,如果需要更换成其他的数据类型(ReturnType中类型列表),并且调整{Sm2Cipher.java}加密器的秘钥编码方式。
4)国秘SM4秘钥长度为16个字符.
2).将密码管理器初始化到UopenCryptionKit4
可以使用时初始化,也可以项目启动是初始化,业务使用一定要制定自己的秘钥,切记不要使用工具内置秘钥,工具内置秘钥只是为了大家快速体验
UEncryptionManager.initKey(new MyEncryptKeySource());
3).关于Op操作符的说明
所有的操作入口都在UEncryptionManager中,对于加密还是解密这里只按传的操作符来确定,方法不变
//加密操作符 Encryption //解密操作符 Decrypt
4).关于方法中的ReturnType数据类型
考虑到不同的业务场景可能会需要不同的数据类型,如A加密场景需要使用Hex数据类型操作,B场景加密数据结果需要Base64类型操作,这里也约定了常见的数据类型HEX,BASE64,STRING,如果您认为都不符合,那么可以直接使用最原始返回Byte自定义数据类型
/** * 返回或解密传入数据普通字符串类型 */ TYPE_STRING, /** * 返回或解密传入数据普通字Base64类型 */ TYPE_BASE64, /** * 返回或解密传入数据普通字16进制类型 */ TYPE_HEX
DEMO.1 AES加解密操作
/** * Aes加解密 * @param content 内容 * @param type 操作类型 * @param returnDataType 返回数据类型(加解密需要统一,内部会对数据做编码) */ String value = UEncryptionManager.getInstance().withAes("10---323_哈哈四大时刻18211!@", Op.Encryption, ReturnType.TYPE_HEX); System.out.println("AES加密后值:" + value); String value1 = UEncryptionManager.getInstance().withAes(value, Op.Decrypt, ReturnType.TYPE_HEX); System.out.println("AES解密后值:" + value1);
DEMO.2 3DES加解密操作
String triple1 = UEncryptionManager.getInstance().withTripleDes("测试3des加解密字符串@(*!*@&!__", Op.Encryption, ReturnType.TYPE_BASE64); System.out.println("3DES加密:" + triple1); String triple2 = UEncryptionManager.getInstance().withTripleDes(triple1, Op.Decrypt, ReturnType.TYPE_BASE64); System.out.println("3DES解密:" + triple2);
DEMO.3 RSA加解密操作
//公钥加密--》私钥解密 String rsaPublic = UEncryptionManager.getInstance().withRsaPublic("测试RSA公钥加解密!@823144aas_*!.>", Op.Encryption, ReturnType.TYPE_BASE64); System.out.println("RSA公钥加密:" + rsaPublic); String rsaPublic1 = UEncryptionManager.getInstance().withRsaPrivate(rsaPublic, Op.Decrypt, ReturnType.TYPE_BASE64); System.out.println("RSA私钥解密:" + rsaPublic1); //私钥加密---》公钥解密 String rsaPrivate = UEncryptionManager.getInstance().withRsaPrivate("测试RSA私钥主导加解密@!@!@!&@*!.>", Op.Encryption, ReturnType.TYPE_HEX); System.out.println("RSA私钥加密:" + rsaPrivate); String rsaPrivate1 = UEncryptionManager.getInstance().withRsaPublic(rsaPrivate, Op.Decrypt, ReturnType.TYPE_HEX); System.out.println("RSA公钥解密:" + rsaPrivate1);
如果你没有秘钥,可以先通过工具{utils/RsaKeyHelper.java}内部提供的秘钥生成器生成秘钥对,然后将生成好的秘钥对在放入秘钥管理器中即可,模式秘钥数据类型为Base64
RsaKeyHelper.KeyPass keyPass= RsaKeyHelper.generateKeyPair(); System.out.println("公钥:"+keyPass.getPublicKey()); System.out.println("私钥:"+keyPass.getPrivateKey());
目前如果需要调整秘钥生成的数据类型,那你可能需要将项目clone到本地进行修改重新打包
修改一,将生成秘钥地方编码方式进行调整
public static synchronized void generateKeyPair() { try { //KEY_SIZE=2048 keyPairGenerator.initialize(KEY_SIZE, new SecureRandom(UUID.randomUUID().toString().getBytes())); keyPair = keyPairGenerator.generateKeyPair(); } catch (Exception e) { e.printStackTrace(); } RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); //需要修改秘钥数据类型,调整此处即可 String publicKeyString = new String(Base64.encode(rsaPublicKey.getEncoded()), Charset.forName("UTF-8")); String privateKeyString = new String(Base64.encode(rsaPrivateKey.getEncoded()), Charset.forName("UTF-8")); storeKey(publicKeyString, PUBLIC_KEY_NAME, PUBLIC_FILENAME); storeKey(privateKeyString, PRIVATE_KEY_NAME, PRIVATE_FILENAME); }
修改二,将秘钥解密初地方进行调整
修改RsaPrivateCipher 中静态类 KeyPairHelper 中方法”getPublicKey”与”getPrivateKey”中秘钥编码类型
//私钥 public static RSAPrivateKey getPrivateKey(String base64KeyPass) throws Exception { RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) certMap.get("PrivateKey" + base64KeyPass.hashCode()); if (rsaPrivateKey != null) { return rsaPrivateKey; } //调整这里 byte[] keyBytes = Base64.decode(base64KeyPass); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec); certMap.put("PrivateKey" + base64KeyPass.hashCode(), rsaPrivateKey); return rsaPrivateKey; } //公钥 public static RSAPublicKey getPublicKey(String base64KeyPass) throws Exception { RSAPublicKey rsaPublicKey = (RSAPublicKey) certMap.get("PublicKey" + base64KeyPass.hashCode()); if (rsaPublicKey != null) { return rsaPublicKey; } //调整这里 byte[] keyBytes = Base64.decode(base64KeyPass); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec); certMap.put("PublicKey" + base64KeyPass.hashCode(), rsaPublicKey); return rsaPublicKey; }
DEMO4. 国秘SM4加解密操作
//SM4加解密-秘钥为16字符长度 String sm4Encry= UEncryptionManager.getInstance().withSm4("测试Sm4对称加密算法——_90a8^$",Op.Encryption,ReturnType.TYPE_BASE64); System.out.println("国秘SM4加密:" + sm4Encry); String sm4Decry= UEncryptionManager.getInstance().withSm4(sm4Encry,Op.Decrypt,ReturnType.TYPE_BASE64); System.out.println("国秘SM4解密:" + sm4Decry);
DEMO5. 国密SM2加解密操作
//客户端公钥加密--》服务端私钥解密 String sm2PublicKeyEncry= UEncryptionManager.getInstance().withSm2PublicKey("这是测试Sm2公钥加密私钥解密的内容)*(*&*&",Op.Encryption,ReturnType.TYPE_HEX); System.out.println("SM2公钥加密:" + sm2PublicKeyEncry); String sm2PrivateKeyDecry= UEncryptionManager.getInstance().withSm2PrivateKey(sm2PublicKeyEncry,Op.Decrypt,ReturnType.TYPE_HEX); System.out.println("SM2私钥解密:" + sm2PrivateKeyDecry);
DEMO6.DSA加签与验证
用于数据签名和验证,校验数据是否完整,或者被篡改,使用说明:
1 生成加签和验证的公私钥 (详细见:DSAKeyHelper.genKeyPair()函数)
2 客户端通过公钥进行加签
3 服务端通过私钥进行签名验证
String dasResult= UEncryptionManager.getInstance().withDasSign("等待Das加签的数据",ReturnType.TYPE_BASE64); System.out.println("DSA加签:" + dasResult); Boolean dasFlag= UEncryptionManager.getInstance().withDasVerify("等待Das加签的数据",dasResult,ReturnType.TYPE_BASE64); System.out.println("DSA公钥签名验证:" + dasFlag);
DEMO7.国密SM3杂凑签名
//SM3签名 String sm3Sign= UEncryptionManager.getInstance().withSm3("测试Sm3签名算法",ReturnType.TYPE_HEX); System.out.println("国秘SM3签名:" + sm3Sign);
DEMO8.HMacSHA1/HMacSHA256 签名
String sign256Base64 = UEncryptionManager.getInstance().withHmacSh256("测试字符串asa@!_a", ReturnType.TYPE_HEX); System.out.println("HmacSh256 指纹:" + sign256Base64); String sign1Base64 = UEncryptionManager.getInstance().withHmacSha1("测试字符串asa@!_a", ReturnType.TYPE_HEX); System.out.println("HmacSha1 指纹:" + sign1Base64);
DEMO9.MD5 指纹
String md5 = UEncryptionManager.getInstance().withMd5("哈哈杀a123456", ReturnType.TYPE_BASE64); System.out.println("md5 指纹:" + md5);
依赖的第三方包
项目依赖了 bcprov-jdk16-1.46 包,主要是未了统一使用的编码工具,避免不同环境使用导致编码数据异常,也使用了内部的底层加密算法。
下一个版本规划
1. 优化密码管理器,使密码管理私有化更灵活。
2.制定Android版本Kit。
3.实现内部注解自动对数据进行加解密操作。
最后
欢迎大家使用,改进建议可以再公众号留言或者GitHub题issue都可,如果可以的话希望一起完善这个库!