Post by Gio » 26 May 2020, 18:11
Poderia Dar Um Exemplo, De Como Fazer O Script Rodar Somente Em Determinada Maquina?
Certo, mas esta é uma rotina que tem muito a ver com a criatividade e o conhecimento de criptografia na verdade, então vou tentar ser o mais simplista possível ok?
Perceba que isso significa que não vou propor um código forte em termos criptográficos. Mas veja que a segurança depende entre outras coisas do segredo do código, então não teria nem como eu recomendar o uso de um exemplo que tornei público, por isso vou escrevê-lo apenas por razões didáticas.
De antemão reitero que o exemplo usará um algoritmo BEEEEEM básico de criptografia que é muito fácil de quebrar. Não é um algoritmo recomendado para nível comercial, só vou usar ele porque é fácil de implementar e o assunto não é exatamente a criptografia em si.
Tendo dito isto, vamos lá
Primeiro você fará na verdade dois scripts, mas um deles ficará com você e o outro será o que já iria para o cliente mesmo.
Um dos scripts (o que vai para o usuário) será o script que você já ia vender pra ele, só que você vai colocar nele duas rotinas especiais acessíveis na tela de login: uma para descriptografar e testar uma chave, e outra para gerar um arquivo indentificador da máquina. O arquivo nada mais é do que uma leitura dos componentes (hardware) e dados da máquina, conforme a rotina descrita no outro post.
Embora seja possível, é extremamente improvável que dois computadores tenham os exatos mesmos valores de hardware, além de que o arquivo também pode conter outras informações ainda mais difíceis de se repetirem (como a data/hora da instalação do Windows).
Então o script do cliente será tipo esse aqui:
Code: Select all
#SingleInstance, Force
Gui, add, Text, x20 y40, Insira a chave validadora do seu ID aqui:
Gui, add, Edit, x20 y60 w360 vCHAVE_INSERIDA
Gui, add, Button, x150 y100 w100 gVERIFICAR_CHAVE, VALIDAR
Gui, add, button, x300 y250 gGERAR_ID, GERAR ID
Gui, add, statusbar, , Bem vindo
Gui, show, w400 h300, Script de chaves de licença
Return
VERIFICAR_CHAVE:
Gui, submit, nohide
Gui, Default
SB_SetText("Verificando chave inserida...")
TENTATIVA_DE_CHAVE := Descriptografar(CHAVE_INSERIDA)
StringSplit, CAMPO_, TENTATIVA_DE_CHAVE, |
If (CAMPO_0 < 5) ; Primeiro, garantimos que a chave inserida tenha pelo menos 5 campos verificáveis.
{
Msgbox, 0x10, Erro, A chave inserida é inválida.
SB_SetText("")
Return
}
RunWait, %comspec% /c systeminfo > tmpFile,,Hide
FileRead, INFO_PC, tmpFile
FileDelete, tmpFile
Loop % CAMPO_0 - 1 ; Este loop verifica se os campos da chave inserida estão no arquivo de ID da máquina, então não vamos procurar o último campo (que é a data de validade) aqui ainda.
{
If (!(InStr(INFO_PC, CAMPO_%A_Index%)) AND !(A_Index = CAMPO_0 ))
{
ATUAL := CAMPO_%A_Index%
Msgbox, 0x10, Erro, A chave inserida é inválida. %ATUAL%
SB_SetText("")
Return
}
}
DATA_DA_LICENCA := CAMPO_%CAMPO_0% . "000000"
DATA_PARA_EXIBIR := SubStr(DATA_DA_LICENCA, 7, 2) . "/" . SubStr(DATA_DA_LICENCA, 5, 2) . "/" . SubStr(DATA_DA_LICENCA, 1, 4)
If !(A_Now <= DATA_DA_LICENCA)
{
Msgbox, 0x10, Erro, A chave inserida expirou em %DATA_PARA_EXIBIR%.
Return
}
msgbox, 0, Aviso, Login efetuado com sucesso!
SB_SetText("Login efetuado com sucesso.")
Return
GERAR_ID:
Gui, Default
SB_SetText("Gerando arquivo de ID...")
RunWait, %comspec% /c systeminfo > tmpFile,,Hide
FileRead, INFO_PC, tmpFile
FileDelete, tmpFile
FileSelectFile, CAMINHO_DO_ARQUIVO, S, , Selecione a pasta de destino, Arquivo usid (*.usid) ; Use uma extensão bem diferente para evitar leigos curiosos e associações erradas do arquivo de ID a outras programas da máquina do cliente.
If (ErrorLevel = 1)
{
msgbox, 0x10, Erro, Você precisa selecionar um local para salvar o arquivo de ID.
Return
}
FileAppend, %INFO_PC%, %CAMINHO_DO_ARQUIVO%.usid
If (ErrorLevel = 1)
{
msgbox, 0x10, Erro, Não foi possível gravar o arquivo de ID. Verifique as permissões da pasta e tente novamente.
Return
}
msgbox, 0, Aviso, Arquivo gerado com sucesso. Envie o arquivo ao suporte para geração da chave de acesso.
SB_SetText("Arquivo de ID gerado com sucesso.")
Return
Descriptografar(String)
{
Loop, Parse, String
{
Nova_Letra := Asc(A_LoopField) - 1
Nova_String := Nova_String . Chr(Nova_Letra)
}
Return Nova_String
}
Return
Execute ele e veja que o cliente quando abrir o seu programa terá duas opçoes: inserir uma chave OU gerar um ID.
Ao clicar em "Gerar ID" o script salvará um arquivo na pasta escolhida pelo cliente com as informações da máquina dele (obtidas conforme o código do outro post).
Este arquivo você vai solicitar que ele envie para você por email. Os dados do arquivo podem ser visualizados em qualquer editor de texto, inclusive no bloco de notas do Windows, pois se trata de fato de um arquivo texto, apesar da extensão diferentona (
.usid)
O conteúdo arquivo será tipo este aqui (com mais algumas informações):
Code: Select all
Nome do host: DESKTOP-XCV32CB
Nome do sistema operacional: Microsoft Windows 10 Pro
VersÆo do sistema operacional: 10.0.18362 N/A compila‡Æo 18362
Fabricante do sistema operacional: Microsoft Corporation
Configura‡Æo do SO: Esta‡Æo de trabalho aut“noma
Tipo de compila‡Æo do sistema operacional: Multiprocessor Free
Propriet rio registrado: FULANO
Organiza‡Æo registrada:
Identifica‡Æo do produto: 00338-10004-00001-AB241
Data da instala‡Æo original: 05/03/2020, 16:54:46
Tempo de Inicializa‡Æo do Sistema: 25/05/2020, 08:49:55
Fabricante do sistema: SAMSUNG ELECTRONICS CO., LTD.
Modelo do sistema: 300E5EV/300E4EV/270E5EV/270E4EV/2470EV
Tipo de sistema: x64-based PC
Processador(es): 1 processador(es) instalado(s).
[01]: Intel64 Family 6 Model 58 Stepping 9 GenuineIntel ~2400 Mhz
VersÆo do BIOS: Phoenix Technologies Ltd. P07RBD, 23/10/2013
Pasta do Windows: C:\Windows
Pasta do sistema: C:\Windows\system32
Inicializar dispositivo: \Device\HarddiskVolume1
Localidade do sistema: pt-br;Portuguˆs (Brasil)
Localidade de entrada: pt-br;Portuguˆs (Brasil)
Então o que você tem que fazer é selecionar algumas "palavras" dessas (pelo menos 5 e não selecione elas dos títulos é claro. Cada "palavra" pode conter espaços). Essas palavras devem ser suficientes para você identificar a máquina do cliente. Por exemplo, do arquivo acima eu selecionei estas:
Code: Select all
FULANO
SAMSUNG ELECTRONICS
300E5EV/300E4EV/
P07RBD
05/03/2020, 16:54:46
Veja que estas palavras contém basicamente: o modelo do notebook, o nome do usuário, o fabricante do notebook, um código da versão da BIOS e a data/hora de instalação do windows. Não precisa ser o código completo, mas é importante ser uma parte boa. Eu escolhi exatamente essas "palavras" porque elas se referem ao hardware do computador, que dificilmente será trocado pelo cliente. Além disso, é praticamente impossível tudo isso se repetir na máquina do amigo dele ou em outra máquina qualquer.
Agora vamos ao segundo script.
O script abaixo é o que ficará com você (ou seja, você NÃO vai enviar pro cliente nunca). Não precisa nem compilar ele e nem precisa ter tela, já que é você que vai operar. Ele basicamente transforma uma string (mais uma data de validade que você escolher) em uma chave criptografada. Isso é feito através de um algoritmo criptográfico ridiculamente simples que eu não recomendo o uso, pois é somente para exemplo (simplesmente peguei as palavras, criei uma lista separada por
|, colei a data no final da string, e depois aumentei o código ASCII de cada letra da string final em 1).
Code: Select all
String_Para_Encriptar := "FULANO|SAMSUNG ELECTRONICS|300E5EV/300E4EV/|P07RBD|05/03/2020, 16:54:46" ; ESCREVA AQUI AS PALAVRAS ESCOLHIDAS DO PC ALVO !!
Data_De_Validade := "20200531" ; Formato AAAAMMDD (ano com quatro dígitos, seguido de mês com 2 dígitos, seguido de dia com 2 dígitos. Zeros devem estar presentes em caso de dias e meses menores que 10).
NOVA_CHAVE := Criptografar(String_Para_Encriptar, Data_De_Validade)
Clipboard := NOVA_CHAVE
msgbox, 0, Aviso, Chave gerada com sucesso: `n`n%NOVA_CHAVE% `n`nA chave foi copiada.
Return
Criptografar(String, Data)
{
DADOS := CHAVE . "|" . Data
Loop, Parse, DADOS
{
Nova_Letra := Asc(A_LoopField) + 1
Nova_String := Nova_String . Chr(Nova_Letra)
}
Return Nova_String
}
Return
A chave gerada será então enviada ao cliente para que possa efetuar a validação do seu sistema.
Para validar o sistema, o script do cliente (aquele primeiro deste post), através da rotina do botão "VALIDAR" vai descriptografar a chave (neste caso diminuir 1 no código ANSI de cada letra) e depois vai interpretar as informações da seguinte forma:
Primeiro o script vai repetir a rotina de obtenção daquele arquivo de ID da máquina (embora apenas para uma variável).
Depois, vai cortar os campos da chave criptografada e procurar uma correspondência exata para cada um no arquivo de ID atual da máquina (exceto a data de validade, é claro).
Se as palavras estiverem todas lá, ele vai então comparar o último campo (a data da validade) com a data atual do computador. Se a data for menor que a atual, ele valida.
Você pode (e deve) melhorar essa rotina de comparação da data, para que não fique refém do usuário mudar a data do computador. Tem alguns tópicos discutindo opções (como pegar a data atual online ou usar o registro para gravar sempre a data máxima de execução do script, de modo a poder conferir se a data do computador é maior que ela).
Mas não se esqueça que este exemplo é somente para uma discussão didática, não estou em nenhuma hipótese indicando você a usar essa mesma rotina para um software comercial. Você pode incrementar este código de muitas maneiras para melhorar a sua segurança e eu não me responsabilizo por uma quebra deste algoritmo simples ok
O algoritmo de criptografia utilizado neste exemplo foi a
Cifra de César, e como disse reiteradamente, ele é um dos mais simples de quebrar. Serve apenas para discussões didáticas.
[QUOTE]Poderia Dar Um Exemplo, De Como Fazer O Script Rodar Somente Em Determinada Maquina?[/QUOTE]
Certo, mas esta é uma rotina que tem muito a ver com a criatividade e o conhecimento de criptografia na verdade, então vou tentar ser o mais simplista possível ok?
Perceba que isso significa que não vou propor um código forte em termos criptográficos. Mas veja que a segurança depende entre outras coisas do segredo do código, então não teria nem como eu recomendar o uso de um exemplo que tornei público, por isso vou escrevê-lo apenas por razões didáticas.
De antemão reitero que o exemplo usará um algoritmo BEEEEEM básico de criptografia que é muito fácil de quebrar. Não é um algoritmo recomendado para nível comercial, só vou usar ele porque é fácil de implementar e o assunto não é exatamente a criptografia em si.
Tendo dito isto, vamos lá :beer:
Primeiro você fará na verdade dois scripts, mas um deles ficará com você e o outro será o que já iria para o cliente mesmo.
Um dos scripts (o que vai para o usuário) será o script que você já ia vender pra ele, só que você vai colocar nele duas rotinas especiais acessíveis na tela de login: uma para descriptografar e testar uma chave, e outra para gerar um arquivo indentificador da máquina. O arquivo nada mais é do que uma leitura dos componentes (hardware) e dados da máquina, conforme a rotina descrita no outro post.
:arrow: Embora seja possível, é extremamente improvável que dois computadores tenham os exatos mesmos valores de hardware, além de que o arquivo também pode conter outras informações ainda mais difíceis de se repetirem (como a data/hora da instalação do Windows).
Então o script do cliente será tipo esse aqui:
[code]#SingleInstance, Force
Gui, add, Text, x20 y40, Insira a chave validadora do seu ID aqui:
Gui, add, Edit, x20 y60 w360 vCHAVE_INSERIDA
Gui, add, Button, x150 y100 w100 gVERIFICAR_CHAVE, VALIDAR
Gui, add, button, x300 y250 gGERAR_ID, GERAR ID
Gui, add, statusbar, , Bem vindo
Gui, show, w400 h300, Script de chaves de licença
Return
VERIFICAR_CHAVE:
Gui, submit, nohide
Gui, Default
SB_SetText("Verificando chave inserida...")
TENTATIVA_DE_CHAVE := Descriptografar(CHAVE_INSERIDA)
StringSplit, CAMPO_, TENTATIVA_DE_CHAVE, |
If (CAMPO_0 < 5) ; Primeiro, garantimos que a chave inserida tenha pelo menos 5 campos verificáveis.
{
Msgbox, 0x10, Erro, A chave inserida é inválida.
SB_SetText("")
Return
}
RunWait, %comspec% /c systeminfo > tmpFile,,Hide
FileRead, INFO_PC, tmpFile
FileDelete, tmpFile
Loop % CAMPO_0 - 1 ; Este loop verifica se os campos da chave inserida estão no arquivo de ID da máquina, então não vamos procurar o último campo (que é a data de validade) aqui ainda.
{
If (!(InStr(INFO_PC, CAMPO_%A_Index%)) AND !(A_Index = CAMPO_0 ))
{
ATUAL := CAMPO_%A_Index%
Msgbox, 0x10, Erro, A chave inserida é inválida. %ATUAL%
SB_SetText("")
Return
}
}
DATA_DA_LICENCA := CAMPO_%CAMPO_0% . "000000"
DATA_PARA_EXIBIR := SubStr(DATA_DA_LICENCA, 7, 2) . "/" . SubStr(DATA_DA_LICENCA, 5, 2) . "/" . SubStr(DATA_DA_LICENCA, 1, 4)
If !(A_Now <= DATA_DA_LICENCA)
{
Msgbox, 0x10, Erro, A chave inserida expirou em %DATA_PARA_EXIBIR%.
Return
}
msgbox, 0, Aviso, Login efetuado com sucesso!
SB_SetText("Login efetuado com sucesso.")
Return
GERAR_ID:
Gui, Default
SB_SetText("Gerando arquivo de ID...")
RunWait, %comspec% /c systeminfo > tmpFile,,Hide
FileRead, INFO_PC, tmpFile
FileDelete, tmpFile
FileSelectFile, CAMINHO_DO_ARQUIVO, S, , Selecione a pasta de destino, Arquivo usid (*.usid) ; Use uma extensão bem diferente para evitar leigos curiosos e associações erradas do arquivo de ID a outras programas da máquina do cliente.
If (ErrorLevel = 1)
{
msgbox, 0x10, Erro, Você precisa selecionar um local para salvar o arquivo de ID.
Return
}
FileAppend, %INFO_PC%, %CAMINHO_DO_ARQUIVO%.usid
If (ErrorLevel = 1)
{
msgbox, 0x10, Erro, Não foi possível gravar o arquivo de ID. Verifique as permissões da pasta e tente novamente.
Return
}
msgbox, 0, Aviso, Arquivo gerado com sucesso. Envie o arquivo ao suporte para geração da chave de acesso.
SB_SetText("Arquivo de ID gerado com sucesso.")
Return
Descriptografar(String)
{
Loop, Parse, String
{
Nova_Letra := Asc(A_LoopField) - 1
Nova_String := Nova_String . Chr(Nova_Letra)
}
Return Nova_String
}
Return[/code]
Execute ele e veja que o cliente quando abrir o seu programa terá duas opçoes: inserir uma chave OU gerar um ID.
Ao clicar em "Gerar ID" o script salvará um arquivo na pasta escolhida pelo cliente com as informações da máquina dele (obtidas conforme o código do outro post). [u]Este arquivo você vai solicitar que ele envie para você por email[/u]. Os dados do arquivo podem ser visualizados em qualquer editor de texto, inclusive no bloco de notas do Windows, pois se trata de fato de um arquivo texto, apesar da extensão diferentona ([c].usid[/c])
O conteúdo arquivo será tipo este aqui (com mais algumas informações):
[code]
Nome do host: DESKTOP-XCV32CB
Nome do sistema operacional: Microsoft Windows 10 Pro
VersÆo do sistema operacional: 10.0.18362 N/A compila‡Æo 18362
Fabricante do sistema operacional: Microsoft Corporation
Configura‡Æo do SO: Esta‡Æo de trabalho aut“noma
Tipo de compila‡Æo do sistema operacional: Multiprocessor Free
Propriet rio registrado: FULANO
Organiza‡Æo registrada:
Identifica‡Æo do produto: 00338-10004-00001-AB241
Data da instala‡Æo original: 05/03/2020, 16:54:46
Tempo de Inicializa‡Æo do Sistema: 25/05/2020, 08:49:55
Fabricante do sistema: SAMSUNG ELECTRONICS CO., LTD.
Modelo do sistema: 300E5EV/300E4EV/270E5EV/270E4EV/2470EV
Tipo de sistema: x64-based PC
Processador(es): 1 processador(es) instalado(s).
[01]: Intel64 Family 6 Model 58 Stepping 9 GenuineIntel ~2400 Mhz
VersÆo do BIOS: Phoenix Technologies Ltd. P07RBD, 23/10/2013
Pasta do Windows: C:\Windows
Pasta do sistema: C:\Windows\system32
Inicializar dispositivo: \Device\HarddiskVolume1
Localidade do sistema: pt-br;Portuguˆs (Brasil)
Localidade de entrada: pt-br;Portuguˆs (Brasil)[/code]
Então o que você tem que fazer é selecionar algumas "palavras" dessas (pelo menos 5 e não selecione elas dos títulos é claro. Cada "palavra" pode conter espaços). Essas palavras devem ser suficientes para você identificar a máquina do cliente. Por exemplo, do arquivo acima eu selecionei estas:
[code]FULANO
SAMSUNG ELECTRONICS
300E5EV/300E4EV/
P07RBD
05/03/2020, 16:54:46[/code]
:arrow: Veja que estas palavras contém basicamente: o modelo do notebook, o nome do usuário, o fabricante do notebook, um código da versão da BIOS e a data/hora de instalação do windows. Não precisa ser o código completo, mas é importante ser uma parte boa. Eu escolhi exatamente essas "palavras" porque elas se referem ao hardware do computador, que dificilmente será trocado pelo cliente. Além disso, é praticamente impossível tudo isso se repetir na máquina do amigo dele ou em outra máquina qualquer.
Agora vamos ao segundo script.
O script abaixo é o que ficará com você (ou seja, você NÃO vai enviar pro cliente nunca). Não precisa nem compilar ele e nem precisa ter tela, já que é você que vai operar. Ele basicamente transforma uma string (mais uma data de validade que você escolher) em uma chave criptografada. Isso é feito através de um algoritmo criptográfico ridiculamente simples que eu não recomendo o uso, pois é somente para exemplo (simplesmente peguei as palavras, criei uma lista separada por [c]|[/c], colei a data no final da string, e depois aumentei o código ASCII de cada letra da string final em 1).
[code]String_Para_Encriptar := "FULANO|SAMSUNG ELECTRONICS|300E5EV/300E4EV/|P07RBD|05/03/2020, 16:54:46" ; ESCREVA AQUI AS PALAVRAS ESCOLHIDAS DO PC ALVO !!
Data_De_Validade := "20200531" ; Formato AAAAMMDD (ano com quatro dígitos, seguido de mês com 2 dígitos, seguido de dia com 2 dígitos. Zeros devem estar presentes em caso de dias e meses menores que 10).
NOVA_CHAVE := Criptografar(String_Para_Encriptar, Data_De_Validade)
Clipboard := NOVA_CHAVE
msgbox, 0, Aviso, Chave gerada com sucesso: `n`n%NOVA_CHAVE% `n`nA chave foi copiada.
Return
Criptografar(String, Data)
{
DADOS := CHAVE . "|" . Data
Loop, Parse, DADOS
{
Nova_Letra := Asc(A_LoopField) + 1
Nova_String := Nova_String . Chr(Nova_Letra)
}
Return Nova_String
}
Return
[/code]
A chave gerada será então enviada ao cliente para que possa efetuar a validação do seu sistema.
Para validar o sistema, o script do cliente (aquele primeiro deste post), através da rotina do botão "VALIDAR" vai descriptografar a chave (neste caso diminuir 1 no código ANSI de cada letra) e depois vai interpretar as informações da seguinte forma:
Primeiro o script vai repetir a rotina de obtenção daquele arquivo de ID da máquina (embora apenas para uma variável).
Depois, vai cortar os campos da chave criptografada e procurar uma correspondência exata para cada um no arquivo de ID atual da máquina (exceto a data de validade, é claro).
Se as palavras estiverem todas lá, ele vai então comparar o último campo (a data da validade) com a data atual do computador. Se a data for menor que a atual, ele valida.
:arrow: Você pode (e deve) melhorar essa rotina de comparação da data, para que não fique refém do usuário mudar a data do computador. Tem alguns tópicos discutindo opções (como pegar a data atual online ou usar o registro para gravar sempre a data máxima de execução do script, de modo a poder conferir se a data do computador é maior que ela).
:arrow: Mas não se esqueça que este exemplo é somente para uma discussão didática, não estou em nenhuma hipótese indicando você a usar essa mesma rotina para um software comercial. Você pode incrementar este código de muitas maneiras para melhorar a sua segurança e eu não me responsabilizo por uma quebra deste algoritmo simples ok :beer:
O algoritmo de criptografia utilizado neste exemplo foi a [url=https://pt.wikipedia.org/wiki/Cifra_de_C%C3%A9sar]Cifra de César[/url], e como disse reiteradamente, ele é um dos mais simples de quebrar. Serve apenas para discussões didáticas.