WEB—加密算法
Posted Zx770
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WEB—加密算法相关的知识,希望对你有一定的参考价值。
前言:在渗透测试中,常见的密码等敏感信息会采用加密处理,
其中作为安全测试人员必须要了解常见的加密方式,才能为后续的安全测试做好准备
————————————————————————————————————————————
常见加密编码等算法解析
-
MD5,SHA,ASC,进制,时间戳,URL,BASE64,Unescape,AES,DES 等
MD5是最常见的加密方式,市面上绝大部分网站的管理员密码或者用户密码都是用MD5加密,分为两种16MD5和MD5。16MD5加密后的密文是16位的长度,MD5是32位长度。加密字符串一般是由数字0-9和字母a-z组成。
SHA:有SHA1、SHA256、SHA384、SHA512,明文越长,加密后的密文也就越长,加密字符串也是由数字0-9和字母a-z组成。
进制在这儿省略。
时间戳:脚本语言、数据库和一些应用,看时间是采用时间戳,与人为不一样。
URL是访问网站时网址上的一些信息,以百分号(%)开始后面加上由0-9或a-z组合成的两位字符就是URL编码。
BASE64是最常见的编码方式,明文越长,密文也会越长。由0-9&A-Z&a-z组合的字符串,经常会在字符串的后面出现一个=或者两个==或者没有。
Unescape与URL有点类似,以百分号%开始,后面接u+4个数字,每一个%u1111对应明文的两个字符,若明文字符数是双数,则以%u0000结尾,若为单数,则不为%u0000结尾。主要应用在web应用。
AES可以说是继MD5后的另一种加密方式,是一种安全的加密方式,涉及到填充,数据块,密码和偏移量四种选择。数据块选择的位数越大,加密的强度越深。偏移量是选择从某个地方开始加密,不会从期初开始。输出会进行一个BASE64转换。有时候出现“/”在密文里。
如果碰到类似于BASE64的编码转码后出现乱码,可以考虑是AES加密。对AES进行解密必须要满足四个条件:密码、偏移量、填充方式和数据块。不能缺密码和偏移量,填充方式和数据块可以逐个尝试。
DES类似于BASE64,明文越长,密文也就越长。 有时候会出现“+”在密文里。
常见加密形式算法解析
-
直接加密,带 salt,带密码,带偏移,带位数,带模式,带干扰,自定义组合等
常见解密方式
-
枚举,自定义逆向算法,可逆向
了解常规加密算法的特性
-
长度位数,字符规律,代码分析,搜索获取等
md5(md5($pass).$salt)意思是先对密码进行md5加密,加密后加盐再进行md5加密。
Java Web学习数据加密方式详解
本文借鉴:chengbinbbs,FKNIGHT0X,Central-Perk(特此感谢!)
对称加密
定义:加密和解密使用相同密钥的算法。
常见的有DES、3DES、AES、PBE等加密算法,这几种算法安全性依次是逐渐增强的。
DES加密
特点:简便、密钥长度比较短。
/** * DES加密介绍 * DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究, * 后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力, * 24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现 * 。 * 注意:DES加密和解密过程中,密钥长度都必须是8的倍数 */ public class DESUtil /** * 加密 * * @param datasource byte[] 需要加密的数据.getBytes() * @param password String 密码(作用:生成密钥,长度要是8的倍数) * @return byte[] */ public static byte[] encrypt(byte[] datasource, String password) try SecureRandom random = new SecureRandom(); // 使用密码,创建一个DESKeySpec对象 DESKeySpec desKey = new DESKeySpec(password.getBytes()); //创建一个密匙工厂,然后用它把DESKeySpec转换成对应的密钥 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); //根据密钥工厂的入参生成对应的des密钥 SecretKey securekey = keyFactory.generateSecret(desKey); //Cipher对象实际完成加密操作 Cipher cipher = Cipher.getInstance("DES"); //用密匙初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, securekey, random); //现在,获取数据并加密 //正式执行加密操作 return cipher.doFinal(datasource); catch (Throwable e) e.printStackTrace(); return null; /** * 解密 * * @param src byte[] 密钥加密过后的信息 * @param password String * @return byte[] * @throws Exception */ public static byte[] decrypt(byte[] src, String password) throws Exception // DES算法要求有一个可信任的随机数源 SecureRandom random = new SecureRandom(); // 创建一个DESKeySpec对象 DESKeySpec desKey = new DESKeySpec(password.getBytes()); // 创建一个密匙工厂 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); // 将DESKeySpec对象转换成SecretKey对象 SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher对象实际完成解密操作 Cipher cipher = Cipher.getInstance("DES"); // 用密匙初始化Cipher对象 cipher.init(Cipher.DECRYPT_MODE, securekey, random); // 真正开始解密操作 return cipher.doFinal(src); //测试 public static void main(String args[]) //待加密内容 String str = "测试内容"; //密码,长度要是8的倍数 String password = "9588028820109132570743325311898426347857298773549468758875018579537757772163084478873699447306034466200616411960574122434059469100235892702736860872901247123456"; byte[] result = DESUtil.encrypt(str.getBytes(), password); System.out.println("加密后:" + new String(result)); //直接将如上内容解密 try byte[] decryResult = DESUtil.decrypt(result, password); System.out.println("解密后:" + new String(decryResult)); catch (Exception e1) e1.printStackTrace();
AES加密
/** * AES 加密方法,是对称的密码算法(加密与解密的密钥一致),这里使用最大的 256 位的密钥 */ public class AESUtil /** * 获得一个 密钥长度为 256 位的 AES 密钥, * * @return 返回经 BASE64 处理之后的密钥字符串 */ public static String getStrKeyAES() throws NoSuchAlgorithmException, UnsupportedEncodingException //密钥生成器,指定生成AES类型的密钥 KeyGenerator keyGen = KeyGenerator.getInstance("AES"); //加密的强随机数 SecureRandom secureRandom = new SecureRandom(String.valueOf(System.currentTimeMillis()).getBytes("utf-8")); //初始化密钥生成器的长度为256位 keyGen.init(256, secureRandom); // 这里可以是 128、192、256、越大越安全 //生成密钥 SecretKey secretKey = keyGen.generateKey(); //Base64.getEncoder():使用base64编码来编码字节数据 return Base64.getEncoder().encodeToString(secretKey.getEncoded()); /** * 将使用 Base64 加密后的字符串类型的 SecretKey 解码为 SecretKey * * @param strKey * @return SecretKey */ public static SecretKey strKey2SecretKey(String strKey) byte[] bytes = Base64.getDecoder().decode(strKey); SecretKeySpec secretKey = new SecretKeySpec(bytes, "AES"); return secretKey; /** * 加密 * * @param content 待加密内容 * @param secretKey 加密使用的 AES 密钥 * @return 加密后的密文 byte[] */ public static byte[] encryptAES(byte[] content, SecretKey secretKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return cipher.doFinal(content); /** * 解密 * * @param content 待解密内容 * @param secretKey 解密使用的 AES 密钥 * @return 解密后的明文 byte[] */ public static byte[] decryptAES(byte[] content, SecretKey secretKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, secretKey); return cipher.doFinal(content);
非对称加密
定义:非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。一般公钥是公开的,私钥是自己保存。
常见的有RSA算法
RSA加密
/** * RSA公钥/私钥/签名工具包 * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式 * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密, * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 * * @author IceWee * @version 1.0 * @date 2012-4-26 */ public class RSAUtils /** */ /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * 获取公钥的key */ private static final String PUBLIC_KEY = "RSAPublicKey"; /** * 获取私钥的key */ private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * 生成密钥对(公钥和私钥) * * @return * @throws Exception */ public static Map<String, Object> genKeyPair() throws Exception //实例化一个密钥对生成器,并设置长度 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); //生成密钥对 KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //公钥、私钥 Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; /** * 用私钥对信息生成数字签名 * * @param data 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception //解码私钥 byte[] keyBytes = Base64.decode(privateKey).getBytes(); //以编码格式来表示私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); //根据RSA算法创建key工厂,并使用PKCS8编码生成一个私钥 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); //签名算法 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return new String(Base64.encode(signature.sign())); /** * 校验数字签名 * * @param data 已加密数据 * @param publicKey 公钥(BASE64编码) * @param sign 数字签名 * @return * @throws Exception */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception //解码公钥 byte[] keyBytes = Base64.decode(publicKey).getBytes(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64.decode(sign).getBytes()); /** * 私钥解密 * * @param encryptedData 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception byte[] keyBytes = Base64.decode(privateKey).getBytes(); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) if (inputLen - offSet > MAX_DECRYPT_BLOCK) cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); else cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; /** * 公钥解密 * * @param encryptedData 已加密数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception byte[] keyBytes = Base64.decode(publicKey).getBytes(); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) if (inputLen - offSet > MAX_DECRYPT_BLOCK) cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); else cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; /** * 公钥加密 * * @param data 源数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception byte[] keyBytes = Base64.decode(publicKey).getBytes(); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) if (inputLen - offSet > MAX_ENCRYPT_BLOCK) cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); else cache = cipher.doFinal(data, offSet, inputLen - offSet); out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; /** * 私钥加密 * * @param data 源数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception byte[] keyBytes = Base64.decode(privateKey).getBytes(); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) if (inputLen - offSet > MAX_ENCRYPT_BLOCK) cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); else cache = cipher.doFinal(data, offSet, inputLen - offSet); out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; /** * 获取私钥 * * @param keyMap 密钥对 * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception Key key = (Key) keyMap.get(PRIVATE_KEY); return new String(Base64.encode(key.getEncoded())); /** * 获取公钥 * * @param keyMap 密钥对 * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception Key key = (Key) keyMap.get(PUBLIC_KEY); return new String(Base64.encode(key.getEncoded()));
以上是关于WEB—加密算法的主要内容,如果未能解决你的问题,请参考以下文章