数据安全--水印和溯源工具

水印工具

简介

水印有很多种,一般分明水印和盲水印。明水印可直接看到,盲水印直接隐藏在资源中。如:重复的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));
			
		}
		
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值