Documentação
/

Chave de codificação do array de bytecode

Externalizando a chave de codificação do array de bytecode

Pro

Forneça sua própria chave de criptografia de bytecode da VM com vmBytecodeArrayEncodingKey e devolva-a em tempo de execução por meio de um key getter - mantida fora do bundle, lida do armazenamento do cliente ou obtida do seu backend.

O que essas opções fazem

vmBytecodeArrayEncoding criptografa o array de bytecode da VM para que ele não fique na saída como texto puro. Por padrão, a chave de criptografia é derivada do ambiente e reconstruída no cliente, de modo que você nunca precisa lidar com ela. Isso é conveniente, mas o material da chave ainda reside no bundle.

Duas opções permitem que você retire a chave do bundle e a controle você mesmo:

  • vmBytecodeArrayEncodingKey - a chave que você fornece em tempo de compilação. Quando definida, ela é usada no lugar da chave padrão derivada do ambiente e não é incorporada na saída ofuscada.
  • vmBytecodeArrayEncodingKeyGetter - uma expressão JavaScript que retorna essa mesma chave em tempo de execução. Ela é incorporada literalmente e avaliada no navegador quando o código ofuscado é carregado.

O objetivo é a separação: como a chave não está no código, uma varredura puramente estática do bundle não consegue recuperá-la. Ela ainda precisa estar presente em tempo de execução para que o código funcione, portanto não é verdadeiramente secreta - mas você decide de onde ela vem e quem pode vê-la.

Essas duas opções formam um par. vmBytecodeArrayEncodingKey sem um getter deixa o código ofuscado sem nenhuma forma de obter a chave em tempo de execução, e um getter sem uma chave de tempo de compilação correspondente não tem nada com que concordar. Defina ambas, junto com vmBytecodeArrayEncoding: true.

Como as duas chaves se combinam

Sua chave nunca é usada sozinha - em ambos os lados ela é combinada com uma chave interna controlada pelo ofuscador:

  • Tempo de compilação. vmBytecodeArrayEncodingKey é combinada com uma chave interna que o ofuscador deriva, e o array de bytecode é codificado com a chave mista resultante.
  • Tempo de execução. O valor para o qual seu vmBytecodeArrayEncodingKeyGetter é resolvido é combinado com a mesma chave interna, reconstruída no cliente a partir de vários fatores de tempo de execução, para decodificar o bytecode.

Como ambos os lados combinam sua chave com a chave interna, o getter deve ser resolvido para exatamente a mesma string que você passou como vmBytecodeArrayEncodingKey. Nenhuma das partes é suficiente sozinha: sua chave sem a chave interna não consegue decodificar o bytecode, e a chave interna é inútil sem a sua - e é por isso que controlar quem recebe sua chave é o que realmente protege o código.

Fornecendo a chave em tempo de execução

Por padrão, o getter é síncrono: a expressão deve retornar a chave imediatamente quando o código ofuscado é carregado. Leia-a de qualquer fonte que já esteja presente no cliente - um cookie, localStorage, uma variável global ou um elemento do DOM injetado pelo servidor.

JavaScript

A chave deve existir antes de o código ofuscado ser executado:

JavaScript

Outras fontes síncronas funcionam da mesma forma - escolha aquela que seu aplicativo já preenche:

JavaScript

Mantenha a chave fora do mesmo arquivo ou script do código ofuscado. Colocá-la ali inline anula todo o propósito - uma varredura estática do bundle recuperaria tanto o código quanto sua chave. Armazene-a em uma fonte separada e injete a chave de tempo de compilação vmBytecodeArrayEncodingKey a partir de uma variável de ambiente ou de um segredo, em vez de fazer commit dela.

Obtendo a chave do seu backend (assíncrono)

Requer vmAsyncExecutor · v7.3.0+

Um getter síncrono só pode ler o que já está no cliente. Para obter a chave do seu servidor - de modo que você possa protegê-la por trás de autenticação e revogá-la - o getter precisa ser assíncrono, e isso requer vmAsyncExecutor. Com o executor assíncrono ativado, o getter pode retornar uma Promise, e a VM a aguarda antes de executar.

JavaScript

Um getter que retorna uma Promise requer vmAsyncExecutor. Isso não pode ser verificado em tempo de build, portanto um getter com Promise e vmAsyncExecutor desativado falha em tempo de execução - o decodificador recebe o objeto Promise em vez da string da chave.

Autorize a entrega da chave com uma sessão validada e as verificações de licença necessárias. Origin ou Referer sozinhos não autenticam o cliente; requisições GET de mesma origem podem omitir Origin. Desative o cache. Vincule as chaves à versão correta e implante chaves e bundles juntos. Um cliente que recebe a chave pode inspecioná-la em execução.

JavaScript

Quando a chave não corresponde

O código ofuscado só funciona quando o getter retorna exatamente a mesma chave usada durante a ofuscação. Se as chaves diferem - ou se o getter retorna undefined, null ou uma string vazia - a descriptografia produz um keystream errado e o código falha em tempo de execução com saída sem sentido ou com um erro comum de tempo de execução.

Deliberadamente, não há uma mensagem de erro distinta e específica da chave: uma chave que falhou é indistinguível de qualquer outra falha em tempo de execução. Portanto, quando um bundle protegido pela VM lança um erro apenas quando essa opção está em uso, verifique primeiro o caminho da chave - que o getter seja resolvido na página, retorne uma string não vazia e retorne o mesmo valor com o qual você fez a build.