首页 文章 精选 留言 我的

精选列表

搜索[密码管理],共10000篇文章
优秀的个人博客,低调大师

【Java小工匠聊密码学】--数字签名-DSA

1、DSA数字签名概述 1.1 DSA加密算算法 DSA(Digital Signature Algorithm)是Schnorr和ElGamal签名算法的变种,被美国NIST作为数字签名标准(DigitalSignature Standard)。 DSA(Digital Signature Algorithm,数字签名算法,用作数字签名标准的一部分),它是另一种公开密钥算法,它不能用作加密,只用作数字签名。DSA使用公开密钥,为接受者验证数据的完整性和数据发送者的身份。它也可用于由第三方去确定签名和所签数据的真实性。DSA算法的安全性基于解离散对数的困难性,这类签字标准具有较大的兼容性和适用性,成为网络安全体系的基本构件之一。 2、DSA数字签名算法分类 DSA只能与SHA-1一起使用。 3、DSA数字签名实现 3.1 JDK实现 package lzf.cipher.jdk; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; /** * @author java小工匠 */ public class JdkSignatureDsaUtils { public static final String DSA = "DSA"; public static final String MD5withDSA = "SHAwithDSA"; // 初始化密钥对 public static KeyPair initKey() { try { KeyPairGenerator generator = KeyPairGenerator.getInstance(DSA); // 512 -65536 && 64 的倍数 generator.initialize(1024); return generator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } // 获取公钥 public static byte[] getPublicKey(KeyPair keyPair) { byte[] bytes = keyPair.getPublic().getEncoded(); return bytes; } // 获取公钥 public static String getPublicKeyStr(KeyPair keyPair) { byte[] bytes = keyPair.getPublic().getEncoded(); return encodeHex(bytes); } // 获取私钥 public static byte[] getPrivateKey(KeyPair keyPair) { byte[] bytes = keyPair.getPrivate().getEncoded(); return bytes; } // 获取私钥 public static String getPrivateKeyStr(KeyPair keyPair) { byte[] bytes = keyPair.getPrivate().getEncoded(); return encodeHex(bytes); } // 签名 public static byte[] sign(byte[] data, byte[] privateKey, String type) { try { // 还原使用 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory keyFactory = KeyFactory.getInstance(DSA); PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 1、实例化Signature Signature signature = Signature.getInstance(type); // 2、初始化Signature signature.initSign(priKey); // 3、更新数据 signature.update(data); // 4、签名 return signature.sign(); } catch (Exception e) { throw new RuntimeException(e); } } // 验证 public static boolean verify(byte[] data, byte[] publicKey, byte[] sign, String type) { try { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory keyFactory = KeyFactory.getInstance(DSA); PublicKey pubKey = keyFactory.generatePublic(keySpec); // 1、实例化Signature Signature signature = Signature.getInstance(type); // 2、初始化Signature signature.initVerify(pubKey); // 3、更新数据 signature.update(data); // 4、签名 return signature.verify(sign); } catch (Exception e) { throw new RuntimeException(e); } } // 数据准16进制编码 public static String encodeHex(final byte[] data) { return encodeHex(data, true); } // 数据转16进制编码 public static String encodeHex(final byte[] data, final boolean toLowerCase) { final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; final char[] toDigits = toLowerCase ? DIGITS_LOWER : DIGITS_UPPER; final int l = data.length; final char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return new String(out); } public static void main(String[] args) { String str = "java小工匠"; byte[] data = str.getBytes(); // 初始化密钥度 KeyPair keyPair = initKey(); byte[] publicKey = getPublicKey(keyPair); byte[] privateKey = getPrivateKey(keyPair); // 签名 String type = MD5withDSA; byte[] sign = sign(str.getBytes(), privateKey, type); // 验证 boolean b = verify(data, publicKey, sign, type); System.out.println("验证:" + b); } }

优秀的个人博客,低调大师

【Java小工匠聊密码学】--base58编码

1、Base58编码概述 1.1 什么是Base58编码? Base58是比特币的一种特殊编码方式,主要用于产生比特币钱包地址。相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+"和"/"符号。 1.2 Base58的设计目的? Base58编码,为比特币比特币钱包地址设计的。 (1)避免混淆,在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。 (2)Base64编码中包含"+"和"/",非字母或数字的字符串作为帐号较难被接受。 (3) 在邮件系统中,使用字符和数字的组合,不容易换行。 (4)双击可以选中整个字符串。 1.3 Base58编码表 Base58编码 1.4 Base58编码原理 Base58编码实际上是58进制,和2进制、8进制、16进制是一样的道理,只是用58作为进制的单位了,正好和58个不容易混淆的字符对应。 1.5 Base58Check 二进制数据的传输过程中,为了防止数据传输的错误,保护数据安全,通常会加一个校验码。通过校验码的配合可以发现数据是否被破坏或者是否在发送时输入错误了。Base58Check就是Base58加上校验码,或者可以说是Base58的一种编码形式,在比特币系统中生成钱包地址的时候就使用到了这种编码形式。 2、Base58编码实现 2.1 比特币Base58 比特币中的Base58编码,不是纯正的Base58,包含一部分比特币地址规范,例如前导0的处理。 package lzf.cipher.jdk; import java.util.Arrays; /** * 复制比特币源码,去掉与Base58编码无关功能 * * @author java小工匠 */ public class Base58 { // Bsae58 编码表 public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); private static final char ENCODED_ZERO = ALPHABET[0]; private static final int[] INDEXES = new int[128]; static { Arrays.fill(INDEXES, -1); for (int i = 0; i < ALPHABET.length; i++) { INDEXES[ALPHABET[i]] = i; } } // Base58 编码 public static String encode(byte[] input) { if (input.length == 0) { return ""; } // 统计前导0 int zeros = 0; while (zeros < input.length && input[zeros] == 0) { ++zeros; } // 复制一份进行修改 input = Arrays.copyOf(input, input.length); // 最大编码数据长度 char[] encoded = new char[input.length * 2]; int outputStart = encoded.length; // Base58编码正式开始 for (int inputStart = zeros; inputStart < input.length;) { encoded[--outputStart] = ALPHABET[divmod(input, inputStart, 256, 58)]; if (input[inputStart] == 0) { ++inputStart; } } // 输出结果中有0,去掉输出结果的前端0 while (outputStart < encoded.length && encoded[outputStart] == ENCODED_ZERO) { ++outputStart; } // 处理前导0 while (--zeros >= 0) { encoded[--outputStart] = ENCODED_ZERO; } // 返回Base58 return new String(encoded, outputStart, encoded.length - outputStart); } public static byte[] decode(String input) { if (input.length() == 0) { return new byte[0]; } // 将BASE58编码的ASCII字符转换为BASE58字节序列 byte[] input58 = new byte[input.length()]; for (int i = 0; i < input.length(); ++i) { char c = input.charAt(i); int digit = c < 128 ? INDEXES[c] : -1; if (digit < 0) { String msg = "Invalid characters,c=" + c; throw new RuntimeException(msg); } input58[i] = (byte) digit; } // 统计前导0 int zeros = 0; while (zeros < input58.length && input58[zeros] == 0) { ++zeros; } // Base58 编码转 字节序(256进制)编码 byte[] decoded = new byte[input.length()]; int outputStart = decoded.length; for (int inputStart = zeros; inputStart < input58.length;) { decoded[--outputStart] = divmod(input58, inputStart, 58, 256); if (input58[inputStart] == 0) { ++inputStart; } } // 忽略在计算过程中添加的额外超前零点。 while (outputStart < decoded.length && decoded[outputStart] == 0) { ++outputStart; } // 返回原始的字节数据 return Arrays.copyOfRange(decoded, outputStart - zeros, decoded.length); } // 进制转换代码 private static byte divmod(byte[] number, int firstDigit, int base, int divisor) { int remainder = 0; for (int i = firstDigit; i < number.length; i++) { int digit = (int) number[i] & 0xFF; int temp = remainder * base + digit; number[i] = (byte) (temp / divisor); remainder = temp % divisor; } return (byte) remainder; } public static void main(String[] args) { byte[] data = new byte[] {0,0,58,0,0,59}; String dataStr = Base58.encode(data); System.out.println("Base58编码后:"+dataStr); byte[] ndata = Base58.decode(dataStr); for (byte b : ndata) { System.out.println(b); } } } 如果读完觉得有收获的话,欢迎点赞、关注、加公众号【小工匠技术圈】 个人公众号,欢迎关注,查阅更多精彩历史! image

优秀的个人博客,低调大师

【Java小工匠聊密码学】--非对称加密--RSA

1、什么是RSA 算法 RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。 对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。 2、RSA算法过程 3、RAS算法实现 3.1、JDK算法实现 package lzf.cipher.jdk; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; /** * @author Java小工匠 */ public class JdkRsaUtils { // 初始化密钥对 public static KeyPair initKey() { try { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); // 512 -65536 && 64 的倍数 generator.initialize(1024); return generator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } // 获取公钥 public static byte[] getPublicKey(KeyPair keyPair) { byte[] bytes = keyPair.getPublic().getEncoded(); return bytes; } // 获取公钥 public static String getPublicKeyStr(KeyPair keyPair) { byte[] bytes = keyPair.getPublic().getEncoded(); return encodeHex(bytes); } // 获取私钥 public static byte[] getPrivateKey(KeyPair keyPair) { byte[] bytes = keyPair.getPrivate().getEncoded(); return bytes; } // 获取私钥 public static String getPrivateKeyStr(KeyPair keyPair) { byte[] bytes = keyPair.getPrivate().getEncoded(); return encodeHex(bytes); } // 加密数据 public static byte[] encryptRsa(byte[] data, byte[] key) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); RSAPublicKey secretKey = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.PUBLIC_KEY, secretKey); byte[] rs = cipher.doFinal(data); return rs; } catch (Exception e) { throw new RuntimeException(e); } } // 解密数据 public static byte[] decryptRsa(byte[] data, byte[] key) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key); RSAPrivateCrtKey secretKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.PRIVATE_KEY, secretKey); byte[] rs = cipher.doFinal(data); return rs; } catch (Exception e) { throw new RuntimeException(e); } } // 数据准16进制编码 public static String encodeHex(final byte[] data) { return encodeHex(data, true); } // 数据转16进制编码 public static String encodeHex(final byte[] data, final boolean toLowerCase) { final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; final char[] toDigits = toLowerCase ? DIGITS_LOWER : DIGITS_UPPER; final int l = data.length; final char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return new String(out); } public static void main(String[] args) throws Exception { String str = "java小工匠"; KeyPair keyPair = initKey(); byte[] publicKey = getPublicKey(keyPair); byte[] privateKey = getPrivateKey(keyPair); byte[] secretData = encryptRsa(str.getBytes(), publicKey); System.out.println("RSA加密:" + encodeHex(secretData)); byte[] data = decryptRsa(secretData, privateKey); System.out.println("RSA解密:" + new String(data)); } }

优秀的个人博客,低调大师

【Java小工匠聊密码学】--消息摘要--HMAC算法

1、什么是HMAC HMAC是密钥相关的消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。 2、HMAC用途 我们使用MD和SHA 消息摘要算法,可以保证数据的完整性。但是在网络传输场景下,消息发送者,仅发送原始数据和数据摘要信息是,黑客可以伪装原始数据和数据摘要信息,达到攻击的目的,HMAC算法通过密钥和数据共同生成 消息摘要,黑客在不知道密钥的情况下,伪造数据和消息摘要难度进一步加大。 消息发送 3、HMAC算法分类 算法种类 摘要长度 HmacMD5 128 HmacSHA1 160 HmacSHA256 256 HmacSHA384 384 HmacSHA512 512 4、HMAC算法实现 4.1 JDK 算法实现 package lzf.cipher.jdk; import java.nio.charset.Charset; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * @author java小工匠 */ public class JdkHmacUtils { // 获取 HmacMD5 Key public static byte[] getHmacMd5Key() { return getHmacKey("HmacMD5"); } // 获取 HmacSHA256 public static byte[] getHmacSha256Key() { return getHmacKey("HmacSHA256"); } // 获取 HmacSHA512 public static byte[] getHmacSha512Key() { return getHmacKey("HmacSHA512"); } // 获取 HMAC Key public static byte[] getHmacKey(String type) { try { // 1、创建密钥生成器 KeyGenerator keyGenerator = KeyGenerator.getInstance(type); // 2、产生密钥 SecretKey secretKey = keyGenerator.generateKey(); // 3、获取密钥 byte[] key = secretKey.getEncoded(); return key; } catch (Exception e) { throw new RuntimeException(e); } } // HMAC MD5 加密 public static String encryptHmacMD5(byte[] data, byte[] key) { return encryptHmac(data, key, "HmacMD5"); } // HMAC SHA256 加密 public static String encryptHmacSHA256(byte[] data, byte[] key) { return encryptHmac(data, key, "HmacSHA256"); } // HMAC SHA521 加密 public static String encryptHmacSHA512(byte[] data, byte[] key) { return encryptHmac(data, key, "HmacSHA512"); } // 基础MAC 算法 public static String encryptHmac(byte[] data, byte[] key, String type) { try { // 1、还原密钥 SecretKey secretKey = new SecretKeySpec(key, type); // 2、创建MAC对象 Mac mac = Mac.getInstance(type); // 3、设置密钥 mac.init(secretKey); // 4、数据加密 byte[] bytes = mac.doFinal(data); // 5、生成数据 String rs = encodeHex(bytes); return rs; } catch (Exception e) { throw new RuntimeException(e); } } // 数据准16进制编码 public static String encodeHex(final byte[] data) { return encodeHex(data, true); } // 数据转16进制编码 public static String encodeHex(final byte[] data, final boolean toLowerCase) { final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; final char[] toDigits = toLowerCase ? DIGITS_LOWER : DIGITS_UPPER; final int l = data.length; final char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return new String(out); } public static void main(String[] args) { byte[] data = "java小工匠".getBytes(Charset.forName("UTF-8")); // MD5 byte[] hmacMd5KeyBytes = getHmacMd5Key(); String hexHamcMd5Key = encodeHex(hmacMd5KeyBytes); System.out.println("HMAC Md5 密钥:" + hexHamcMd5Key); String hmacMd5Encrypt = encryptHmacMD5(data, hmacMd5KeyBytes); System.out.println("HMAC Md5 加密:" + hmacMd5Encrypt); // SHA256 byte[] hmacSha256KeyBytes = getHmacSha256Key(); String hexHamcSha256Key = encodeHex(hmacSha256KeyBytes); System.out.println("HMAC SHA256 密钥:" + hexHamcSha256Key); String hmacSha256Encrypt = encryptHmacSHA256(data, hmacSha256KeyBytes); System.out.println("HMAC SHA256 加密:" + hmacSha256Encrypt); // SHA512 byte[] hmacSha512KeyBytes = getHmacSha512Key(); String hexHamcSha512Key = encodeHex(hmacSha512KeyBytes); System.out.println("HMAC SHA512 密钥:" + hexHamcSha512Key); String hmacSha512Encrypt = encryptHmacSHA512(data, hmacSha512KeyBytes); System.out.println("HMAC SHA512 加密:" + hmacSha512Encrypt); } } 4.2 CC 算法实现 package lzf.cipher.cc; import java.nio.charset.Charset; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.HmacAlgorithms; import org.apache.commons.codec.digest.HmacUtils; /** * @author java小工匠 */ public class CCHmacUtils { // 获取 HmacMD5 Key public static byte[] getHmacMd5Key() { return getHmacKey("HmacMD5"); } // 获取 HmacSHA256 public static byte[] getHmacSha256Key() { return getHmacKey("HmacSHA256"); } // 获取 HmacSHA512 public static byte[] getHmacSha512Key() { return getHmacKey("HmacSHA512"); } // 获取 HMAC Key public static byte[] getHmacKey(String type) { try { // 1、创建密钥生成器 KeyGenerator keyGenerator = KeyGenerator.getInstance(type); // 2、产生密钥 SecretKey secretKey = keyGenerator.generateKey(); // 3、获取密钥 byte[] key = secretKey.getEncoded(); return key; } catch (Exception e) { throw new RuntimeException(e); } } // HMAC MD5 加密 public static String encryptHmacMD5(byte[] data, byte[] key) { Mac mac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_MD5, key); return Hex.encodeHexString(mac.doFinal(data)); } // HMAC SHA256 加密 public static String encryptHmacSHA256(byte[] data, byte[] key) { Mac mac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_256, key); return Hex.encodeHexString(mac.doFinal(data)); } // HMAC SHA521 加密 public static String encryptHmacSHA512(byte[] data, byte[] key) { Mac mac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_512, key); return Hex.encodeHexString(mac.doFinal(data)); } public static void main(String[] args) { byte[] data = "java小工匠".getBytes(Charset.forName("UTF-8")); // MD5 byte[] hmacMd5KeyBytes = getHmacMd5Key(); String hexHamcMd5Key = Hex.encodeHexString(hmacMd5KeyBytes); System.out.println("HMAC Md5 密钥:" + hexHamcMd5Key); String hmacMd5Encrypt = encryptHmacMD5(data, hmacMd5KeyBytes); System.out.println("HMAC Md5 加密:" + hmacMd5Encrypt); // SHA256 byte[] hmacSha256KeyBytes = getHmacSha256Key(); String hexHamcSha256Key = Hex.encodeHexString(hmacSha256KeyBytes); System.out.println("HMAC SHA256 密钥:" + hexHamcSha256Key); String hmacSha256Encrypt = encryptHmacSHA256(data, hmacSha256KeyBytes); System.out.println("HMAC SHA256 加密:" + hmacSha256Encrypt); // SHA512 byte[] hmacSha512KeyBytes = getHmacSha512Key(); String hexHamcSha512Key = Hex.encodeHexString(hmacSha512KeyBytes); System.out.println("HMAC SHA512 密钥:" + hexHamcSha512Key); String hmacSha512Encrypt = encryptHmacSHA512(data, hmacSha512KeyBytes); System.out.println("HMAC SHA512 加密:" + hmacSha512Encrypt); } } 4.3 BC 算法实现 package lzf.cipher.bc; import java.nio.charset.Charset; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.util.encoders.Hex; /** * @author java小工匠 */ public class BCHmacUtils { // 获取 HmacMD5 Key public static byte[] getHmacMd5Key() { return getHmacKey("HmacMD5"); } // 获取 HmacSHA256 public static byte[] getHmacSha256Key() { return getHmacKey("HmacSHA256"); } // 获取 HmacSHA512 public static byte[] getHmacSha512Key() { return getHmacKey("HmacSHA512"); } // 获取 HMAC Key public static byte[] getHmacKey(String type) { try { // 1、创建密钥生成器 KeyGenerator keyGenerator = KeyGenerator.getInstance(type); // 2、产生密钥 SecretKey secretKey = keyGenerator.generateKey(); // 3、获取密钥 byte[] key = secretKey.getEncoded(); return key; } catch (Exception e) { throw new RuntimeException(e); } } // HMAC MD5 加密 public static String encryptHmacMD5(byte[] data, byte[] key) { HMac hmac = new HMac(new MD5Digest()); hmac.update(data, 0, data.length); byte[] rsData = new byte[hmac.getMacSize()]; hmac.doFinal(rsData, 0); return Hex.toHexString(rsData); } // HMAC SHA256 加密 public static String encryptHmacSHA256(byte[] data, byte[] key) { HMac hmac = new HMac(new SHA256Digest()); hmac.update(data, 0, data.length); byte[] rsData = new byte[hmac.getMacSize()]; hmac.doFinal(rsData, 0); return Hex.toHexString(rsData); } // HMAC SHA521 加密 public static String encryptHmacSHA512(byte[] data, byte[] key) { HMac hmac = new HMac(new SHA512Digest()); hmac.update(data, 0, data.length); byte[] rsData = new byte[hmac.getMacSize()]; hmac.doFinal(rsData, 0); return Hex.toHexString(rsData); } public static void main(String[] args) { byte[] data = "java小工匠".getBytes(Charset.forName("UTF-8")); // MD5 byte[] hmacMd5KeyBytes = getHmacMd5Key(); String hexHamcMd5Key = Hex.toHexString(hmacMd5KeyBytes); System.out.println("HMAC Md5 密钥:" + hexHamcMd5Key); String hmacMd5Encrypt = encryptHmacMD5(data, hmacMd5KeyBytes); System.out.println("HMAC Md5 密钥:" + hmacMd5Encrypt); // SHA256 byte[] hmacSha256KeyBytes = getHmacSha256Key(); String hexHamcSha256Key = Hex.toHexString(hmacSha256KeyBytes); System.out.println("HMAC SHA256 密钥:" + hexHamcSha256Key); String hmacSha256Encrypt = encryptHmacSHA256(data, hmacSha256KeyBytes); System.out.println("HMAC SHA256 密钥:" + hmacSha256Encrypt); // SHA512 byte[] hmacSha512KeyBytes = getHmacSha256Key(); String hexHamcSha512Key = Hex.toHexString(hmacSha512KeyBytes); System.out.println("HMAC SHA512 密钥:" + hexHamcSha512Key); String hmacSha512Encrypt = encryptHmacSHA512(data, hmacSha512KeyBytes); System.out.println("HMAC SHA512 密钥:" + hmacSha512Encrypt); } } 如果读完觉得有收获的话,欢迎点赞、关注、加公众号【小工匠技术圈】 个人公众号,欢迎关注,查阅更多精彩历史! image

优秀的个人博客,低调大师

【Java小工匠聊密码学】--base64编码

1、Base64 概述 1.1 什么是Base64编码 可以将任意的字节数组数据,通过算法,生成只有(大小写英文、数字、+、/)(一共64个字符)内容表示的字符串数据。即将任意的内容转换为可见的字符串形式。 1.2、Base64 编码表 Base64编码表 1.3、Base64 算法由来 以前发送邮件只支持可见字符的传送。由此,需要有一个方法将不可见的字符转换为可见的字符,便产生了Base64编码算法。 1.4、Base64 与 加密关系 (1)Base 64不是加密算法,是一种编码解码算法,通过Base64编码的数据,可以解码回来。 (2) 如果把Base64 一定要把Base64 理解为加密算法的话,Base64 是公布密钥的加密算法。加密原则:公布算法,但是不公布密钥 2、Base64 编码算法 2.1 编码规则 (1)将数据按照 3个字节一组的形式进行处理,每三个字节在编码之后被转换为4个字节。(即:如果一个数据有6个字节,可编码后将包含6/3*4=8个字节) (2)当数据的长度无法满足3的倍数的情况下,最后的数据需要进行填充操作,即补“=” ,这里“=”是填充字符,不要理解为第65个字符 2.2 编码过程 编码规则 (1) 将原始数据3个一组,按位进行分割为 每6位一个字节的形式,进行转换,形成新的4个字节。这四个字节才通过Base64编码表进行映射,形成最后实际的Base64编码结果。 (2)如果原始数据最后无法凑成3个字节,则补填充,以“=”作为替换,代表没有数据。 3、Base64 算法应用 (1) Base64 JSON 二进制数据 服务器给客户端在JSON中传递二进制数据 (2) Base64 图片编码 部分小图片使用Base64进行保存。 (3)Base64 在URL中的应用 Base64 在URL编码应用时,由于'+' 和 '-' 会被浏览器进行转义,因此使用'-','_' 替换,在common codec的实现用,有将提供相应的方法。 (4)Base64编码字符显示回车换行 Base64编码,内容非常多时,common codec实现中,可以在生成Base64字符串是,长多超过指定字符串(默认76个字符串)在生成的Base64字符串中加入换行符(默认'\r\n') 4、算法实现 4.1 JDK 实现 package lzf.cipher.jdk; import java.util.Base64; /** * @author Java小工匠 */ public class JdkBase64Utils { // base64 编码 public static String base64Encoder(byte[] bytes) { return Base64.getEncoder().encodeToString(bytes); } // base64 解码 public static byte[] base64Decode(byte[] src) { return Base64.getDecoder().decode(src); } // base64 解码 public static String base64DecodeToStr(byte[] src) { return new String(base64Decode(src)); } public static void main(String[] args) { String base64 = base64Encoder("java小工匠".getBytes()); System.out.println("编码:" + base64); String str = base64DecodeToStr(base64.getBytes()); System.out.println("解码:" + str); } } 4.2 CC 实现 package lzf.cipher.cc; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.StringUtils; /** * @author Java小工匠 */ public class CCBase64Utils { // base64 编码 public static String base64Encoder(byte[] bytes) { return Base64.encodeBase64String(bytes); } // base64 解码 public static byte[] base64Decode(byte[] src) { return Base64.decodeBase64(src); } // base64 解码 public static String base64DecodeToStr(byte[] src) { return new String(base64Decode(src)); } // CC base64编码,编码长度超过76个字符,添加\r\n 字符进行换行 public static String base64EncodeToChunkedStr(byte[] data) { byte[] bytes = Base64.encodeBase64(data, true); return StringUtils.newStringUsAscii(bytes); } // 使用'-' 和 '_' 下划线替换Base64 编码中的 '+' 和 '/',解决 URL传输问题 public static String base64EncodeToURLSafeString(byte[] data) { return Base64.encodeBase64URLSafeString(data); } public static void main(String[] args) { String base64 = base64Encoder("java小工匠".getBytes()); System.out.println("编码:" + base64); String str = base64DecodeToStr(base64.getBytes()); System.out.println("解码:" + str); String strNewLine = "如果base64超过76个字符,Base64编码就会产生换行,默认添加\r\n符号!"; String ccBase64Chunked = base64EncodeToChunkedStr(strNewLine.getBytes()); System.out.println(ccBase64Chunked); System.out.println("========================"); String strUrl = "URLBase64编码,使用'-'和'_'替换'+'和'/'"; String ccBBase64Url = base64EncodeToURLSafeString(strUrl.getBytes()); System.out.println(ccBBase64Url); } } 4.3 BC 实现 package lzf.cipher.bc; import org.bouncycastle.util.encoders.Base64; /** * @author Java小工匠 */ public class BCBase64Utils { // base64 编码 public static String base64Encoder(byte[] bytes) { return Base64.toBase64String(bytes); } // base64 解码 public static byte[] base64Decode(byte[] src) { return Base64.decode(src); } // base64 解码 public static String base64DecodeToStr(byte[] src) { return new String(base64Decode(src)); } public static void main(String[] args) { String base64 = base64Encoder("java小工匠".getBytes()); System.out.println("编码:" + base64); String str = base64DecodeToStr(base64.getBytes()); System.out.println("解码:" + str); } } 如果读完觉得有收获的话,欢迎点赞、关注、加公众号【小工匠技术圈】 个人公众号,欢迎关注,查阅更多精彩历史! image

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册