mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 15:13:55 +08:00
87 lines
2.9 KiB
Python
87 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.core.crypto import sm2_decrypt_c1c3c2, sm2_encrypt_c1c3c2
|
|
|
|
TARGET_ROOT = Path(__file__).resolve().parents[1]
|
|
REPOSITORY_ROOT = TARGET_ROOT.parents[1]
|
|
VECTOR_PATH = TARGET_ROOT / "tests" / "fixtures" / "sm2-c1c3c2-golden.json"
|
|
BCPROV = (
|
|
REPOSITORY_ROOT
|
|
/ ".runtime"
|
|
/ "m2"
|
|
/ "org"
|
|
/ "bouncycastle"
|
|
/ "bcprov-jdk18on"
|
|
/ "1.78"
|
|
/ "bcprov-jdk18on-1.78.jar"
|
|
)
|
|
JAVA_HOME = REPOSITORY_ROOT / ".runtime" / "jdk" / "bin"
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def vector() -> dict[str, str]:
|
|
return json.loads(VECTOR_PATH.read_text(encoding="utf-8"))
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def java_classpath(tmp_path_factory: pytest.TempPathFactory) -> str:
|
|
classes = tmp_path_factory.mktemp("sm2-java")
|
|
command = [
|
|
str(JAVA_HOME / "javac"),
|
|
"-cp",
|
|
str(BCPROV),
|
|
"-d",
|
|
str(classes),
|
|
str(
|
|
REPOSITORY_ROOT
|
|
/ "main"
|
|
/ "manager-api"
|
|
/ "src"
|
|
/ "main"
|
|
/ "java"
|
|
/ "xiaozhi"
|
|
/ "common"
|
|
/ "utils"
|
|
/ "SM2Utils.java"
|
|
),
|
|
str(TARGET_ROOT / "tests" / "java" / "Sm2InteropCli.java"),
|
|
]
|
|
subprocess.run(command, check=True, capture_output=True, text=True) # noqa: S603
|
|
return f"{classes}:{BCPROV}"
|
|
|
|
|
|
def java_sm2(classpath: str, operation: str, key: str, value: str) -> str:
|
|
result = subprocess.run( # noqa: S603
|
|
[str(JAVA_HOME / "java"), "-cp", classpath, "Sm2InteropCli", operation, key, value],
|
|
check=True,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
return result.stdout
|
|
|
|
|
|
def test_static_java_and_python_vectors_decrypt_in_python(vector: dict[str, str]) -> None:
|
|
assert sm2_decrypt_c1c3c2(vector["privateKey"], vector["javaCiphertext"]) == vector["plaintext"]
|
|
assert sm2_decrypt_c1c3c2(vector["privateKey"], vector["pythonCiphertext"]) == vector["plaintext"]
|
|
|
|
|
|
def test_static_java_and_python_vectors_decrypt_in_java(vector: dict[str, str], java_classpath: str) -> None:
|
|
assert java_sm2(java_classpath, "decrypt", vector["privateKey"], vector["javaCiphertext"]) == vector["plaintext"]
|
|
assert java_sm2(java_classpath, "decrypt", vector["privateKey"], vector["pythonCiphertext"]) == vector["plaintext"]
|
|
|
|
|
|
def test_fresh_ciphertexts_are_bidirectionally_compatible(vector: dict[str, str], java_classpath: str) -> None:
|
|
java_ciphertext = java_sm2(java_classpath, "encrypt", vector["publicKey"], vector["plaintext"])
|
|
assert java_ciphertext.startswith("04")
|
|
assert sm2_decrypt_c1c3c2(vector["privateKey"], java_ciphertext) == vector["plaintext"]
|
|
|
|
python_ciphertext = sm2_encrypt_c1c3c2(vector["publicKey"], vector["plaintext"])
|
|
assert python_ciphertext.startswith("04")
|
|
assert java_sm2(java_classpath, "decrypt", vector["privateKey"], python_ciphertext) == vector["plaintext"]
|