带有OpenSSL的PHP​​中的chacha20-poly1305

时间:2019-02-21 14:40:12

标签: php openssl cryptography php-openssl

我正在运行PHP 7.2.8。根据{{​​1}},chacha20-poly1305是受支持的算法:

import java.util.Comparator;
import java.util.PriorityQueue;

public class Main {

/* Create the open and closed lists */
private static Comparator<Board> comparator = new BoardComparator();
private static PriorityQueue<Board> open = 
        new PriorityQueue<Board>(10, comparator);
private static Closed closed = new Closed();

/* Declare variables that will be used for 
 * purposes of processing the lists and generating
 * child board objects.
 */
private static Board b;
private static int board [][] = new int[4][4];       
private static int cboard1 [][] = new int [4][4];
private static int cboard2 [][] = new int [4][4];
private static String id = new String();
private static int cost = 0;
private static int depth;

public static void main(String[] args) {

    /* Create the root board object*/
    Board root = new Board ();

    run(root);
}

/* Uses the best-first-search algorithm to solve the NQueens puzzle */
public static void run(Board root) {

    /* Enqueue the root board object on the open and closed lists */  
    open.add(root);
    closed.add(root);

    /* While the open list isn't empty */
    while (open.size() != 0){

        /* Dequeue a board object from the open list and 
         * get its depth, cost and the actual board */
        b = open.remove();
        cost = b.getG();   
        depth = b.getH();
        board = b.getBoard();

        /* If the cost of the dequeued a board object is 
         * equal to 0, end processing */
        if (cost == 0){
            System.out.println("\nGoal Achieved ...");
            b.displayBoard();
            System.out.println(b.toString());
            break;
        }

        /* Display the contents of the board object */
        System.out.println("\nEvaluating Board ...");
        b.displayBoard();
        System.out.println(b.toString());

        enumerateChildren();

    }
}

/* Enumerates the next set of child board objects in the graph */
public static void enumerateChildren() {

    /* Get the depth for the child board objects */
    depth += 1;

    System.out.println("\nGenerating Children ...");
    for (int i = 0; i < board.length; i++){            
        for (int j = 0; j < board[i].length; j++){

            /* If the current element is a queen */
            if (board[i][j] == 1){

                /* Copy board and remove the queen from the copies */
                cboard1 = Board.copyBoard(board);
                cboard2 = Board.copyBoard(board);
                cboard1[i][j] = 0;
                cboard2[i][j] = 0;

                if (j == 0){

                    /* If the queen was in the first column, move it
                     * one element to the right and process the child board
                     */                             
                    cboard1[i][j+1] = 1;    
                    processChild(cboard1);

                } else if ((j == 1) || (j == 2)){

                    /* If the queen was in the second or third columns, move it
                     * one element to the right and one element to the left, and
                     * process the child boards
                     */ 
                    cboard1[i][j-1] = 1;
                    cboard2[i][j+1] = 1;
                    processChild(cboard1);
                    processChild(cboard2);                        

                } else {

                    /* If the queen was in the fourth column, move it
                     * one element to the left and process the child board
                     */  
                    cboard1[i][j-1] = 1;
                    processChild(cboard1);            
                }
            }   
        }
    }
}

/* Processes each of the child board objects that has been enumerated */
public static void processChild(int board[][]){

    /* Get id and cost of board */
    id = Board.getId(board);
    cost = Board.evaluateBoard(board);

    /* Create a board Object */
    Board b = new Board (board, id, depth, cost);

    /* If the board object isn't on the closed
     * list, enqueue it on the open and closed lists
     */
    if (!closed.isReviewed(b)){
        open.add(b);
        closed.add(b);

        b.displayBoard();
        System.out.println(b.toString());
    }
  }
}

输出“是”。

所以我尝试使用openssl_get_cipher_methods

echo in_array('chacha20-poly1305', openssl_get_cipher_methods()) ? 'yes' : 'no';

输出PHP警告:

  

警告:openssl_encrypt():无法为不支持AEAD的密码提供经过身份验证的标记

chacha20-poly1305$plaintext = 'zzzzzz'; $key = str_repeat('k', 32); $nonce = str_repeat('n', 12); $aad = ''; $r = openssl_encrypt( $plaintext, 'chacha20-poly1305', $key, OPENSSL_RAW_DATA, $nonce, $newtag, $aad ); echo bin2hex($r);

我能够通过$r获得f4854428b8a8的相同输出(即通过执行此操作没有r):

chacha20

输出相同的事实意味着Poly1305身份验证代码既未添加也未添加至密文。

我的问题是...如何在PHP中使用OpenSSL获得Poly1305身份验证代码?

此外,我知道libsodium提供了chacha20-poly1305支持,但我仍然对它应该如何与OpenSSL一起使用感到好奇。

1 个答案:

答案 0 :(得分:0)

OpenSSL的问题仍未解决(2020年11月),因此如果您需要使用 ChaCha20-Poly1305通过PHP进行身份验证的加密,我建议从 可以实现的Leigh(https://github.com/lt/PHP-AEAD-ChaCha20-Poly1305) 非常简单。

auth-tag($ tag)附加在密文中,需要先分隔 开始解密。

请注意,我正在测试与OpenJDK 11(Java)相同的功能:这两个功能产生相同的密文,但不同身份验证标签,因此它们无法在跨平台中使用环境。

输出:

ChaCha20-Poly1305 encryption with leigh/aead-chacha20-poly1305
tag (16 bytes long, Base64): FK11WpqxhDuJytSgHN86tQ==
ciphertext (Base64):         1rXNtbeGF9KsMZXgPjszIeJ0Ze5ua+Uh5Aexu1ngaH4XoeldG71DwuDEAA==
decrypt: The quick brown fox jumps over the lazy dog

代码(安全警告:切勿在生产中使用静态密钥或随机数):

<?php
# make sure that you used Composer to get "leigh/aead-chacha20-poly1305"
require __DIR__ . '/vendor/autoload.php';

// ### never use static key & nonce in production, this is for testing only ###
$key = '12345678901234567890123456789012'; // 32 bytes
$nonce = '123456789012'; // 12 bytes
$plaintext = 'The quick brown fox jumps over the lazy dog';
$aad = '';

echo 'ChaCha20-Poly1305 encryption with leigh/aead-chacha20-poly1305' . PHP_EOL;
list($ciphertext, $tag) = \ChaCha20Poly1305\encrypt($key, $nonce, $aad, $plaintext);
echo 'tag (16 bytes long, Base64): ' . base64_encode($tag) . PHP_EOL;
echo 'ciphertext (Base64):         ' . base64_encode($ciphertext) . PHP_EOL;
$decrypt = \ChaCha20Poly1305\decrypt($key, $nonce, $aad, $ciphertext, $tag);
echo 'decrypt: ' . $decrypt . PHP_EOL;
?>