带有混淆的回声

xer*_*xes 16 security bash

我需要在屏幕上打印一些变量,但我需要优先混淆前几个字符,我想知道 bash 中是否有一个 echo 命令可以混淆秘密值的第一个字符,同时将其打印到终端:

echo 'secretvalue'
********lue
Run Code Online (Sandbox Code Playgroud)

Jef*_*ler 14

一种选择是强迫自己使用函数而不是echo,例如:

obfuprint() {
  if [ "${#1}" -ge 8 ]
  then
    printf '%s\n' "${1/????????/********}"
  else
    printf '%s\n' "${1//?/*}"
  fi
}
Run Code Online (Sandbox Code Playgroud)

然后你可以调用obfuprint 'secretvalue'和接收********lue(带有尾随换行符)。该函数使用参数扩展来搜索传入值的前八个字符,并用八个星号替换它们。如果传入的值短于八个字符,则它们都将替换为星号。感谢ilkkachu指出我最初假设输入的字符数为 8 个或更多!


受到ilkkachu 的灵活屏蔽答案的启发,我认为添加一个随机屏蔽部分字符串的变体会很有趣:

obfuprintperc () {
  local perc=75  ## percent to obfuscate
  local i=0
  for((i=0; i < ${#1}; i++))
  do
    if [ $(( $RANDOM % 100 )) -lt "$perc" ]
    then
        printf '%s' '*'
    else
        printf '%s' "${1:i:1}"
    fi
  done
  echo
}
Run Code Online (Sandbox Code Playgroud)

这依赖于 bash 的$RANDOM特殊变量;它只是遍历输入的每个字符并决定是屏蔽该字符还是打印它。示例输出:

$ obfuprintperc 0123456789
0*****6*8*
$ obfuprintperc 0123456789
012***678*
$ obfuprintperc 0123456789
**********
$ obfuprintperc 0123456789
*****56***
$ obfuprintperc 0123456789
0*******8*
Run Code Online (Sandbox Code Playgroud)

  • 我也不是固定前缀或可变前缀掩码的粉丝,但是对于那些存在我的秘密的“内核”仍然是秘密的。使用随机掩码,没有“内核”。最终,一切都会向那些足够耐心的人揭示。 (4认同)

ilk*_*chu 13

其他答案从一开始就屏蔽了固定数量的字符,纯文本后缀的长度各不相同。另一种方法是在明文中保留固定数量的字符,并改变掩码部分的长度。我不知道哪个更有用,但这是另一种选择:

#!/bin/bash
mask() {
        local n=3                    # number of chars to leave
        local a="${1:0:${#1}-n}"     # take all but the last n chars
        local b="${1:${#1}-n}"       # take the final n chars 
        printf "%s%s\n" "${a//?/*}" "$b"   # substitute a with asterisks
}

mask abcde
mask abcdefghijkl
Run Code Online (Sandbox Code Playgroud)

这会打印**cde*********jkl


如果您愿意,您还可以修改n短字符串以确保大部分字符串被屏蔽。例如,这将确保即使对于短字符串也至少屏蔽三个字符。(所以abcde->***deabc-> ***):

mask() {
        local n=3
        [[ ${#1} -le 5 ]] && n=$(( ${#1} - 3 ))
        local a="${1:0:${#1}-n}"
        local b="${1:${#1}-n}"
        printf "%s%s\n" "${a//?/*}" "$b"
}
Run Code Online (Sandbox Code Playgroud)


iga*_*gal 8

你可以尝试管道到sed. 例如,要用星号替换字符串的前 8 个字符,您可以通过管道连接到sed 's/^......../********/'命令,例如:

$ echo 'secretvalue' | sed 's/^......../********/'
********lue
Run Code Online (Sandbox Code Playgroud)

您还可以定义一个执行此操作的函数:

obsecho () { echo "$1" | sed 's/^......../*********/'; }
Run Code Online (Sandbox Code Playgroud)

  • 我建议 [`printf` over `echo`](https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo) 这样你就不会受到解释数据的影响例如`\r` 或`\n` (2认同)

Sté*_*las 8

一个zsh变种,掩盖了文字的四分之三:

mask() printf '%s\n' ${(l:$#1::*:)1:$#1*3/4}
Run Code Online (Sandbox Code Playgroud)

例子:

$ mask secretvalue
********lue
$ mask 12345678
******78
$ mask 1234
***4
Run Code Online (Sandbox Code Playgroud)

屏蔽前 8 个字符:

mask() printf '%s\n' ${(l:$#1::*:)1:8}
Run Code Online (Sandbox Code Playgroud)

要屏蔽除最后 3 个字符以外的所有字符:

mask() printf '%s\n' ${(l:$#1::*:)1: -3}
Run Code Online (Sandbox Code Playgroud)

要屏蔽随机数量的字符:

mask() printf '%s\n' ${(l:$#1::*:)1: RANDOM%$#1}
Run Code Online (Sandbox Code Playgroud)