분류 php

JavaScript 및 PHP의 메시지 암호화

컨텐츠 정보

  • 조회 603 (작성일 )

본문

그냥 재미있게, 클라이언트 측 JavaScript로 일부 내용을 암호화하고 PHP 서버가 해독하도록 하십시오. 이는 TLS (HTTPS)를 대체하지 않습니다.


https://dev.to/paragonie/message-encryption-in-javascript-and-php-cg9 


Sodium-Plus를 사용한 JavaScript 암호화 


이를 위해 최신 나트륨 플러스 릴리스를 원할 것입니다. (이 글을 쓰는 현재 버전은 0.4.0입니다.)

<script
  src="/static/js/sodium-plus.min.js"
  integrity="sha384-lv7SVE0eb0bXA3fgK6PwlhViiUwG6tBuMAhS8XX7RvBvyRcdEdJ8HKtFgs4vHTUh"
></script>


다음으로, 메시지를 암호화하고 서버로 보내는 JavaScript 코드를 작성하려고 합니다. 이 예제에서는 jQuery를 사용하지만 XMLHttpRequest 객체를 대신 사용하도록 쉽게 조정할 수 있습니다.


두 가지 함수를 정의해 봅시다. 하나는 하드 코딩 된 문자열에서 CryptographyKey 객체를 로드 합니다. 다른 하나는 실제로 메시지를 암호화합니다.


/**
 * Get the example key. In the real world, you want to generate these randomly.
 */
async function getExampleKey() {
    if (!window.sodium) window.sodium = await SodiumPlus.auto();
    return CryptographyKey.from(
        'e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0',
        'hex'
    );
    // return await sodium.crypto_secretbox_keygen();
}

/**
 * Encrypt a message under a given key.
 */
async function encryptMessage(message, key) {
    if (!window.sodium) window.sodium = await SodiumPlus.auto();

    let nonce = await sodium.randombytes_buf(24);
    let encrypted = await sodium.crypto_secretbox(message, nonce, key);
    return nonce.toString('hex') + encrypted.toString('hex');
}


다음으로, 사용자 입력을 수집하고 암호화하여 서버로 보내는 함수를 작성하려고 합니다.


async function sendEncryptedMessage() {
    let key = await getExampleKey();
    let message = $("#user-input").val();
    let encrypted = await encryptMessage(message, key);
    $.post("/send-message", {"message": encrypted}, function (response) {
        console.log(response);
        $("#output").append("<li><pre>" + response.message + "</pre></li>");
    });
}


... 그리고 일부 지원 HTML :


<label for="user-input">Type a message to encrypt and send:</label>
<textarea id="user-input"></textarea>
<button id="send-it" type="button">Send Encrypted Message</button>
<hr />
<ol id="output"></ol>

<script type="text/javascript">
$("#send-it").on('click', sendEncryptedMessage);
</script>


나트륨을 이용한 PHP 해독 


당신은 paragonie/sodium_compat를 원할 것입니다.


압도적인 확률로 PHP 7.2를 사용하는 경우 내장 된 sodium_ * 함수를 사용할 수 있습니다. 그러나 일부 배포판에서는 기본적으로 나트륨 확장을 잘못 비활성화 할 수 있습니다. 안전하게 플레이 하려면, sodium_compat를 설치하십시오.


프레임 워크 (Symfony, Laravel)를 사용하는 경우 코드가 훨씬 깔끔해 보이지만 설명을 위해 암호 해독 코드는 다음과 같습니다.


<?php
declare(strict_types=1);

require 'vendor/autoload.php'; // Composer

header('Content-Type: application/json');

$key = sodium_hex2bin('e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0');

$encrypted = $_POST['message'] ?? null;
if (!$encrypted) {
    echo json_encode(
        ['message' => null, 'error' => 'no message provided'],
        JSON_PRETTY_PRINT
    );
    exit(1);
}

$nonce = sodium_hex2bin(substr($encrypted, 0, 48));
$ciphertext = sodium_hex2bin(substr($encrypted, 48));
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);

echo json_encode(
    ['message' => $plaintext, 'original' => $encrypted],
    JSON_PRETTY_PRINT
);


Putting it Together 


메시지를 입력하고 버튼을 누르면 메시지가 암호화되어 16 진수로 인코딩 된 문자열이 서버로 전송됩니다.


PHP 코드는 메시지를 해독하고 일반 텍스트를 JSON 응답으로 반환합니다.


그런 다음 JavaScript 코드는 JSON 응답에서 일반 텍스트를 가져 와서 양식 아래의 출력 필드에 추가합니다.


보안 고려 사항 


나트륨 플러스 (JavaScript) 및 libsodium (PHP)을 사용하여 메시지를 암호화 / 암호 해독하는 방법을 보여주는 장난감 예제입니다.


우리는 실제 시스템에서 원하지 않는 많은 단축키를 사용했습니다 (예 : 암호화 키 하드 코딩 및 간결성을 위해 오류 검사 방지).


보다 고급적인 작업 (JavaScript의 공개 키 암호화 및 해당 PHP 함수)을 수행하려면 온라인에서 무료로 설명서를 사용할 수 있습니다.


뻔뻔한 플러그 : JavaScript 또는 PHP 코드를 검토하기 위해 보안 전문가를 찾고 있다면 코드 감사를 위해 Paragon Initiative Enterprises를 고용 해야 하는 이유를 확인하십시오.


추가 자료