AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 507450
Accepted
xerxes
xerxes
Asked: 2019-03-21 06:12:32 +0800 CST2019-03-21 06:12:32 +0800 CST 2019-03-21 06:12:32 +0800 CST

Eco com ofuscação

  • 772

Preciso imprimir algumas variáveis ​​na tela, mas preciso ofuscar preferencialmente os primeiros caracteres e queria saber se havia um comando echo no bash que pode ofuscar os primeiros caracteres de um valor secreto ao imprimi-lo no terminal:

echo 'secretvalue'
********lue
bash security
  • 7 7 respostas
  • 4976 Views

7 respostas

  • Voted
  1. Jeff Schaller
    2019-03-21T06:20:21+08:002019-03-21T06:20:21+08:00

    Uma opção seria forçar-se a usar uma função em vez de echo, como:

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

    Então você pode ligar obfuprint 'secretvalue'e receber ********lue(com uma nova linha à direita). A função usa a expansão de parâmetros para procurar os primeiros oito caracteres do valor passado e os substitui por oito asteriscos. Se o valor de entrada for menor que oito caracteres, todos eles serão substituídos por asteriscos. Obrigado a ilkkachu por apontar minha suposição inicial de oito ou mais entradas de caracteres!


    Inspirado pela resposta de mascaramento flexível do ilkkachu , achei que seria interessante adicionar uma variação que mascarasse aleatoriamente uma porcentagem da string:

    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
    }
    

    Isso depende da $RANDOMvariável especial do bash; ele simplesmente percorre cada caractere da entrada e decide se deve mascarar esse caractere ou imprimi-lo. Saída de amostra:

    $ obfuprintperc 0123456789
    0*****6*8*
    $ obfuprintperc 0123456789
    012***678*
    $ obfuprintperc 0123456789
    **********
    $ obfuprintperc 0123456789
    *****56***
    $ obfuprintperc 0123456789
    0*******8*
    
    • 14
  2. Best Answer
    ilkkachu
    2019-03-21T07:23:48+08:002019-03-21T07:23:48+08:00

    As outras respostas mascaram uma quantidade fixa de caracteres desde o início, com o sufixo de texto simples variando em tamanho. Uma alternativa seria deixar uma quantidade fixa de caracteres em texto simples e variar o comprimento da parte mascarada. Não sei qual é mais útil, mas aqui está a outra opção:

    #!/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
    

    Isso imprime **cdee *********jkl.


    Se desejar, você também pode modificar npara strings curtas para garantir que a maioria da string seja mascarada. Por exemplo, isso garantiria que pelo menos três caracteres fossem mascarados, mesmo para strings curtas. (então abcde-> ***dee abc-> ***):

    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"
    }
    
    • 13
  3. Stéphane Chazelas
    2019-03-21T08:53:11+08:002019-03-21T08:53:11+08:00

    Uma zshvariante que mascara três quartos do texto:

    mask() printf '%s\n' ${(l[$#1][*])1:$#1*3/4}
    

    Exemplo:

    $ mask secretvalue
    ********lue
    $ mask 12345678
    ******78
    $ mask 1234
    ***4
    

    Para mascarar os primeiros 8 caracteres:

    mask() printf '%s\n' ${(l[$#1][*])1:8}
    

    Para mascarar todos, exceto os últimos 3 caracteres:

    mask() printf '%s\n' ${(l[$#1][*])1: -3}
    

    Para mascarar um número aleatório de caracteres:

    mask() printf '%s\n' ${(l[$#1][*])1: RANDOM%$#1}
    
    • 9
  4. igal
    2019-03-21T06:21:44+08:002019-03-21T06:21:44+08:00

    Você pode tentar canalizar para sed. Por exemplo, para substituir os primeiros 8 caracteres de uma string por asteriscos, você pode canalizar para o sed 's/^......../********/'comando, por exemplo:

    $ echo 'secretvalue' | sed 's/^......../********/'
    ********lue
    

    Você também pode definir uma função que faça isso:

    obsecho () { echo "$1" | sed 's/^......../*********/'; }
    
    • 8
  5. LL3
    2019-03-21T13:58:27+08:002019-03-21T13:58:27+08:00

    Outra opção no Bash, se você não se importa com um simples eval, pode fazê-lo com alguns printf:

    # example data
    password=secretvalue
    chars_to_show=3
    
    # the real thing
    eval "printf '*%.0s' {1..$((${#password} - chars_to_show))}"
    printf '%s\n' "${password: -chars_to_show}"
    

    Mas tenha cuidado:

    • corrija o acima conforme necessário quando ${#password}for menor que${chars_to_show}
    • evalpode ser muito perigoso com entrada não confiável: aqui pode ser considerado seguro porque sua entrada vem apenas de fontes seguras, ou seja, o comprimento ${password}e o valor de${chars_to_show}
    • 2
  6. t7e
    2022-05-15T09:59:09+08:002022-05-15T09:59:09+08:00
    $ echo "helloworld" | sed -E "s/(.{3})(.{5})/\1*****/"
    hel*****ld
    

    (.{3})- o mascaramento começa após a 3ª letra
    (.{5})- a quantidade de letras que serão substituídas por *****. (.{255})será o máximo permitido no MacOS BSD sed.

    sed -Epode ser alterado com sed -r, mas sed -Eé mais portátil entre shells.

    • 1
  7. S0AndS0
    2019-03-22T15:23:55+08:002019-03-22T15:23:55+08:00

    Aqui estão alguns scripts Bash de brinquedo para brincar que mostram como combinar pesquisa semelhante a regex com substituição de string.

    strip_str.sh

    #!/usr/bin/env bash
    
    _str="${1}"
    _filter="${2:-'apl'}"
    echo "${_str//[${_filter}]/}"
    
    strip_str.sh 'apple-foo bar'
    # -> e-foo br
    strip_str.sh 'apple-foo bar' 'a'
    # -> pple-foo br
    

    privatize_str.sh

    #!/usr/bin/env bash
    
    _str="${1}"
    _filter="${2:-'apl'}"
    _replace="${3:-'*'}"
    echo "${_str//[${_filter}]/${_replace}}"
    
    privatize_str.sh 'apple-foo bar'
    # -> ****e-foo b*r
    

    restricted_str.sh

    #!/usr/bin/env bash
    
    _str="${1}"
    _valid="${2:-'a-z'}"
    _replace="${3:-''}"
    echo "${_str//[^${_valid}]/${_replace}}"
    
    restricted_str.sh 'apple-foo bar'
    # -> applefoobar
    

    Principais conclusões

    • [a-z 0-9]é totalmente válido e útil, como um <search>dentro ${_var_name//<search>/<replace>}do Bash
    • ^, neste contexto, é o inverso ou notpara pesquisas do tipo regex
    • Os embutidos são geralmente mais rápidos e geralmente mais concisos, especialmente quando cortam tubulações desnecessárias

    Embora eu entenda que printfé melhor em quase todos os casos de uso, o código acima usa echopara não confundir demais o que está acontecendo.

    obfuscate_str.sh

    #!/usr/bin/env bash
    
    _str="${1}"
    _start="${2:-6}"
    _header="$(for i in {1..${_start}}; do echo -n '*'; done)"
    echo "${_header}${_str:${_start}}"
    
    obfuscate_str.sh 'apple-foo bar' 3
    # -> ***le-foo bar
    
    • 0

relate perguntas

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Existe um daemon syslog que implementa RFC 5848 "Signed Syslog Messages"?

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve