首页

分享关于logstash如何实现将敏感数据清除内存中从而避免在数据任意不可控泄露使用SecretStoreUtil源码实现说明

标签:SecretStoreUtil,敏感数据,避免数据泄露,数据安全,logstash,secret     发布时间:2018-04-05   

一、前言

关于logstashlogstash-master.zip源码包中org.logstash.secret.store.SecretStoreUtil数据安全储存工具类,实现敏感数据清除出内存(客户等敏感数据不能储存在内存中),从而避免不可控的数据任意泄露,主要通过常见场景公共方法处理解决问题。

1.将二进制数据转换为字符数据,便于敏感数据识别,方法是asciiBytesToChar、asciiCharToBytes(将处理后的数据还原二进制存储)@b@2.将二进制数据进行base64加密base64Encode处理,避免敏感数据出现,再base64Decode解密输出使用@b@3.直接清除特殊场景二进制数据clearChars@b@4.字符数据随机混淆处理算法deObfuscate、obfuscate

二、源码说明

package org.logstash.secret.store;@b@@b@import java.nio.ByteBuffer;@b@import java.util.Arrays;@b@import java.util.Base64;@b@import java.util.Random;@b@@b@/**@b@ * Conversion utility between String, bytes, and chars. All methods attempt to keep sensitive data out of memory. Sensitive data should avoid using Java {@link String}'s.@b@ */@b@final public class SecretStoreUtil {@b@@b@    /**@b@     * Private constructor. Utility class.@b@     */@b@    private SecretStoreUtil() {@b@    }@b@@b@    private static final Random RANDOM = new Random();@b@@b@    /**@b@     * Converts bytes from ascii encoded text to a char[] and zero outs the original byte[]@b@     *@b@     * @param bytes the bytes from an ascii encoded text (note - no validation is done to ensure ascii encoding)@b@     * @return the corresponding char[]@b@     */@b@    public static char[] asciiBytesToChar(byte[] bytes) {@b@        char[] chars = new char[bytes.length];@b@        for (int i = 0; i < bytes.length; i++) {@b@            chars[i] = (char) bytes[i];@b@            bytes[i] = '\0';@b@        }@b@        return chars;@b@    }@b@@b@    /**@b@     * Converts characters from ascii encoded text to a byte[] and zero outs the original char[]@b@     *@b@     * @param chars the chars from an ascii encoded text (note - no validation is done to ensure ascii encoding)@b@     * @return the corresponding byte[]@b@     */@b@    public static byte[] asciiCharToBytes(char[] chars) {@b@        byte[] bytes = new byte[chars.length];@b@        for (int i = 0; i < chars.length; i++) {@b@            bytes[i] = (byte) chars[i];@b@            chars[i] = '\0';@b@        }@b@        return bytes;@b@    }@b@@b@    /**@b@     * Base64 encode the given byte[], then zero the original byte[]@b@     *@b@     * @param b the byte[] to base64 encode@b@     * @return the base64 encoded bytes@b@     */@b@    public static byte[] base64Encode(byte[] b) {@b@        byte[] bytes = Base64.getEncoder().encode(b);@b@        clearBytes(b);@b@        return bytes;@b@    }@b@@b@    /**@b@     * Base64 encode the given byte[], then zero out the original byte[]@b@     *@b@     * @param bytes the byte[] to base64 encode@b@     * @return the char[] representation of the base64 encoding@b@     */@b@    public static char[] base64EncodeToChars(byte[] bytes) {@b@        return asciiBytesToChar(base64Encode(bytes));@b@    }@b@@b@    /**@b@     * Base64 encode the given char[], then zero out the original char[]@b@     *@b@     * @param chars the char[] to base64 encode@b@     * @return the char[] representation of the base64 encoding@b@     */@b@    public static char[] base64Encode(char[] chars) {@b@        return asciiBytesToChar(base64Encode(asciiCharToBytes(chars)));@b@    }@b@@b@    /**@b@     * Decodes a Base64 encoded byte[], then zero out the original byte[]@b@     *@b@     * @param b the base64 bytes@b@     * @return the non-base64 encoded bytes@b@     */@b@    public static byte[] base64Decode(byte[] b) {@b@        byte[] bytes = Base64.getDecoder().decode(b);@b@        clearBytes(b);@b@        return bytes;@b@    }@b@@b@    /**@b@     * Decodes a Base64 encoded char[], then zero out the original char[]@b@     *@b@     * @param chars the base64 chars@b@     * @return the non-base64 encoded chars@b@     */@b@    public static byte[] base64Decode(char[] chars) {@b@        return base64Decode(asciiCharToBytes(chars));@b@    }@b@@b@    /**@b@     * Attempt to keep data out of the heap.@b@     *@b@     * @param chars the bytes to zero out@b@     */@b@    public static void clearChars(char[] chars) {@b@        Arrays.fill(chars, '\0');@b@    }@b@@b@    /**@b@     * Attempt to keep data out of the heap.@b@     *@b@     * @param bytes the bytes to zero out@b@     */@b@    public static void clearBytes(byte[] bytes) {@b@        Arrays.fill(bytes, (byte) '\0');@b@    }@b@@b@@b@    /**@b@     * De-obfuscates the obfuscated char[] generated by {@link SecretStoreUtil#obfuscate(char[])}@b@     *@b@     * @param chars The chars to de-obscure@b@     * @return the de-obscured chars@b@     */@b@    public static char[] deObfuscate(char[] chars) {@b@        byte[] bytes = asciiCharToBytes(chars);@b@        byte[] random = Arrays.copyOfRange(bytes, bytes.length / 2, bytes.length);@b@        byte[] deObfuscated = new byte[random.length];@b@        for (int i = 0; i < random.length; i++) {@b@            int xor = bytes[i] ^ random[i];@b@            deObfuscated[i] = ((byte) (xor & 0xff));@b@        }@b@        return asciiBytesToChar(deObfuscated);@b@    }@b@@b@    /**@b@     * <p>Simple obfuscation that adds a bit of randomness and shuffles the bits of a char[].</p>@b@     * <p>Note - this is NOT security and will only deter the lazy.</p>@b@     *@b@     * @param chars The chars to obscure@b@     * @return the obscured bytes@b@     */@b@    public static char[] obfuscate(char[] chars) {@b@        byte[] bytes = asciiCharToBytes(chars);@b@        byte[] random = new byte[bytes.length];@b@        RANDOM.nextBytes(random);@b@@b@        ByteBuffer obfuscated = ByteBuffer.allocate(bytes.length * 2);@b@        for (int i = 0; i < bytes.length; i++) {@b@            int xor = bytes[i] ^ random[i];@b@            obfuscated.put((byte) (0xff & xor));@b@        }@b@        obfuscated.put(random);@b@        char[] result = asciiBytesToChar(obfuscated.array());@b@        clearBytes(obfuscated.array());@b@        return result;@b@    }@b@}