水印工具
简介
水印有很多种,一般分明水印和盲水印。明水印可直接看到,盲水印直接隐藏在资源中。如:重复的dom元素覆盖实现, canvas输出背景图,svg实现背景图,图片加水印,视频加水印,音频加水印等等
demo
watermark.js 部分
let watermark = {}
let setWatermark = (str) => {
let id = '3.234384164.34787345845'
if (document.getElementById(id) !== null) {
document.body.removeChild(document.getElementById(id))
}
let can = document.createElement('canvas')
can.width = 600
can.height = 400
let cans = can.getContext('2d')
cans.rotate(-18 * Math.PI / 180)
cans.font = '16px Vedana'
cans.fillStyle = 'rgba(200, 200, 200, 0.30)'
// cans.fillStyle = 'rgba(235, 187, 222,1)'
cans.textAlign = 'left'
cans.textBaseline = 'Middle'
cans.fillText(str, can.width / 3, can.height / 2)
let div = document.createElement('div')
div.id = id
div.style.pointerEvents = 'none'
div.style.top = '70px'
div.style.left = '0px'
div.style.position = 'fixed'
div.style.zIndex = '100000'
div.style.width = document.documentElement.clientWidth - 100 + 'px'
div.style.height = document.documentElement.clientHeight - 100 + 'px'
div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat'
document.body.appendChild(div)
return id
}
// 该方法只允许调用一次
watermark.set = (str) => {
let id = setWatermark(str)
setInterval(() => {
if (document.getElementById(id) === null) {
id = setWatermark(str)
}
}, 500)
window.onresize = () => {
setWatermark(str)
}
}
export default watermark
test.vue嵌入代码使用部分:
import waterMark from "@/utils/watermark";
mounted() {
let userId = "test" // localStorage.getItem("username");
waterMark.set(userId);
}
指纹采集
demo
fingerprintjs测试代码, 直接可用于waf攻击拦截信息采集部分:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Fingerprint2 TEST</title>
<style>
body {
color: #555;
}
#info {
font-size: 12px;
}
#control span {
color: #333;
margin-left: 10px;
}
</style>
</head>
<body>
<div id="info">
<p>纯前端实现的浏览器指纹采集器,通过获取浏览器中所有能获取到的信息(部分通过base64转成String),最后生成出md5,用于该用户在该设备上的唯一标识码,官方宣称准确度高达99.5%</p>
</div>
<div id="control">
<button onclick="start()">开始</button>
<span>userAgent:</span><input type="checkbox" id="userAgent" checked="checked">
<span>fonts:</span><input type="checkbox" id="fonts" checked="checked">
<span>fontsFlash:</span><input type="checkbox" id="fontsFlash" checked="checked">
<span>canvas:</span><input type="checkbox" id="canvas" checked="checked">
<span>webgl:</span><input type="checkbox" id="webgl" checked="checked">
<span>audio:</span><input type="checkbox" id="audio" checked="checked">
<span>enumerateDevices:</span><input type="checkbox" id="enumerateDevices" checked="checked">
</div>
<div id="view">
</div>
<script src="https://cdn.staticfile.org/fingerprintjs2/2.1.0/fingerprint2.min.js"></script>
<script>
function start() {
const start = new Date().getTime();
let view = document.querySelector('#view');
view.innerHTML = '';
let excludes = {};
if (!document.querySelector('#userAgent').checked) {
excludes.userAgent = true;
}
if (!document.querySelector('#audio').checked) {
excludes.audio = true;
}
if (!document.querySelector('#enumerateDevices').checked) {
excludes.enumerateDevices = true;
}
if (!document.querySelector('#fonts').checked) {
excludes.fonts = true;
}
if (!document.querySelector('#fontsFlash').checked) {
excludes.fontsFlash = true;
}
if (!document.querySelector('#webgl').checked) {
excludes.webgl = true;
}
if (!document.querySelector('#canvas').checked) {
excludes.canvas = true;
}
let options = {excludes: excludes}
Fingerprint2.get(options, function (components) {
// 参数
const values = components.map(function (component) {
return component.value
});
// 指纹
const murmur = Fingerprint2.x64hash128(values.join(''), 31);
view.innerHTML += '<p>指纹 : ' + murmur + '</p>';
view.innerHTML += '<p>消耗 : ' + (new Date().getTime() - start) + ' 毫秒</p>';
view.innerHTML += '<p>使用的参数 : </p>';
for (const c of components) {
view.innerHTML += '<p>' + c.key + ' : ' + c.value + '</p>';
}
});
}
</script>
</body>
</html>
数据脱敏
数据脱敏一般这些方式:置换,位移,混淆,掩码(遮盖),加密等。
先列举加解密,其它方式网上也有公开,后续再补充demo。
加解密
rsa加解密和签名
package test;
import java.security.*;
//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;
import java.util.Base64;
import javax.crypto.Cipher;
/**
* 非对称加密RSA
* @author 0x00
*/
public class RSAUtils {
/**
* 公钥加密
* @param content
* @param publicKey
* @return
* @throws Exception
*/
public static String encrypt(String data, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//加密的数据必须为字节
return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
}
/**
* 私钥解密
* @param content
* @param privateKey
* @return
* @throws Exception
*/
public static String decrypt(String data, PrivateKey privateKey) throws Exception {
byte[] bytes = Base64.getDecoder().decode(data);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(cipher.doFinal(bytes));
}
/**
* 签名
* @param data
* @param privateKey
* @return
* @throws Exception
* @throws Exception
*/
public static String sign(String content, byte[] privateKeyBytes) throws Exception
{
//单例获取key工厂类,将拿到的privateKeyBytes创建PKCS8EncodedKeySpec对象,通过其获取PrivateKey对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 用key工厂对象生成私钥
PrivateKey priKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
//获取Signature对象,签名算法为SHA1WithRSA,此处还有较多可选择比如MD2withRSA/MD5withRSA/SHA1withRSA/SHA256withRSA等
Signature signature = Signature.getInstance("SHA1WithRSA");
//初始化签名
signature.initSign(priKey);
//签名的数据必须为字节
signature.update(content.getBytes());
byte[] encodeResult = signature.sign();
return Base64.getEncoder().encodeToString(encodeResult);
}
/**
* 验证
* @param data
* @param sign
* @param publicKey
* @return
* @throws Exception
*/
public static boolean verify(String content, String sign, byte[] publicKeyBytes) throws Exception {
byte[] bytes = Base64.getDecoder().decode(sign);
//单例获取key工厂类,将拿到的publicKey创建X509EncodedKeySpec对象,通过其获取PublicKey对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
//获取Signature对象,签名算法为SHA1WithRSA,此处还有较多可选择比如MD2withRSA/MD5withRSA/SHA1withRSA/SHA256withRSA等
Signature signature = Signature.getInstance("SHA1WithRSA");
signature.initVerify(pubKey);
signature.update( content.getBytes() );
boolean bverify = signature.verify( bytes );
return bverify;
}
/**
* 生成密钥对
* @return
* @throws Exception
*/
public static KeyPair genKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
return keyPairGenerator.generateKeyPair();
}
public static void main(String[] args) throws Exception {
String data = "this is a securet message dfgsgdfgfgdfg";
KeyPair keyPair = genKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
byte[] publicKeyBytes = publicKey.getEncoded();
byte[] privateKeyBytes = privateKey.getEncoded();
// 获取公,私钥,并以base64格式打印出来
// System.out.println("公钥:" + Base64.getEncoder().encodeToString( publicKeyBytes ) );
// System.out.println("私钥:" + Base64.getEncoder().encodeToString( privateKeyBytes ) );
// 公钥加密
String encryptedString = encrypt(data, publicKey);
System.out.println("加密后:" + encryptedString);
System.out.println("加密后的数据长度: " + encryptedString.length() );
// 私钥解密
String decryptedString = decrypt(encryptedString, privateKey);
System.out.println("解密后:" + decryptedString);
// 私钥签名
String sign = sign(data, privateKeyBytes);
System.out.println("签名:" + sign);
System.out.println("签名后的数据长度:" + sign.length() );
// 公钥验签
boolean flag = verify(data, sign, publicKeyBytes);
System.out.println("验证:" + flag);
}
}
AES加解密
package test;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
public class DemoAESUtil {
/**
* 加密
* @param str
* @param key
* @return
* @throws Exception
*/
public static String encrypt(String str, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, generateKey(key));
byte[] bytes = cipher.doFinal(str.getBytes());
return Base64.getEncoder().encodeToString(bytes);
}
/**
* 解密
* @param str
* @param key
* @return
* @throws Exception
*/
public static String decrypt(String str, String key) throws Exception {
byte[] bytes = Base64.getDecoder().decode(str);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, generateKey(key));
return new String(cipher.doFinal(bytes));
}
/**
* 生成key
* @param key
* @return
* @throws Exception
*/
private static Key generateKey(String key) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128, new SecureRandom(key.getBytes())); // 密钥长度 128/192/256
return new SecretKeySpec(keyGenerator.generateKey().getEncoded(), "AES");
}
public static void main(String[] args) throws Exception {
String str = "hello world";
String key = "password";
// 加密
String encryptedString = encrypt(str, key);
System.out.println("加密后:" + encryptedString);
// 解密
String decryptedString = decrypt(encryptedString, key);
System.out.println("解密后:" + new String(decryptedString));
}
}