我的目标是创建一个小型C程序,它将生成输出,以后可以通过PHP解析(现在有一个内置的libsodium包装器)。
我遇到的问题是PHP对C程序的输出抱怨不已。这可能不足为奇,因为我对PHP非常有经验,但对C的经验却很有限。
例如,在PHP中运行sodium_crypto_box_seal_open()
包装器会产生空输出。
我的PHP用法是正确的,因为我已经使用PHP包装器编写了以下C代码的完整实现,并且它工作正常(加密正确并正确解密)。所以我怀疑问题是我输入PHP的C输出。
这是我的C代码(// Encrypt file START
和// Encrypt file END
标签之间的核心文件加密内容是来自libsodium网站的示例代码,其余的是我的新手C编码!):
#include <sodium.h>
#include "filedata.h"
#include <stdio.h>
#include <string.h>
#define CHUNK_SIZE 8192
void doEncrypt(char * inKey,char * plainText,char * cipherText,char * outKey) {
//Get input key
//const char *inputKey=readFile(inKey);
const char *inputKey="aQFsJJuU65zXKzqDfS1KuxqqebkER/cPqno+oZL5PgQ="; // testing with a fixed value....
unsigned char * inputKeyBin=sodium_malloc(crypto_box_PUBLICKEYBYTES);
size_t bin_len;
const char *b64_end;
if (sodium_base642bin(inputKeyBin,sizeof(inputKeyBin),inputKey,strlen(inputKey),NULL,&bin_len,&b64_end,sodium_base64_VARIANT_ORIGINAL) !=0) {
printf("sodium_base642bin() failure\n");
exit(1);
}
// Encrypt file START
unsigned char *key;
unsigned char buf_in[CHUNK_SIZE];
unsigned char buf_out[CHUNK_SIZE+crypto_secretstream_xchacha20poly1305_ABYTES];
unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
crypto_secretstream_xchacha20poly1305_state st;
FILE *fp_t,*fp_s;
unsigned long long out_len;
size_t rlen;
int eof;
unsigned char tag;
key=(unsigned char *)sodium_malloc(crypto_secretstream_xchacha20poly1305_KEYBYTES);
crypto_secretstream_xchacha20poly1305_keygen(key);
fp_s = fopen(plainText, "rb");
fp_t = fopen(cipherText, "wb");
crypto_secretstream_xchacha20poly1305_init_push(&st, header, key);
fwrite(header, 1, sizeof header, fp_t);
do {
rlen = fread(buf_in, 1, sizeof buf_in, fp_s);
eof = feof(fp_s);
tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0;
crypto_secretstream_xchacha20poly1305_push(&st, buf_out, &out_len, buf_in, rlen,
NULL, 0, tag);
fwrite(buf_out, 1, (size_t) out_len, fp_t);
} while (! eof);
fclose(fp_t);
fclose(fp_s);
// Seal Key
unsigned char * sealed=sodium_malloc(crypto_box_SEALBYTES+crypto_secretstream_xchacha20poly1305_KEYBYTES);
if (crypto_box_seal(sealed, key, crypto_secretstream_xchacha20poly1305_KEYBYTES, inputKeyBin) !=0) {
printf("crypto_box_seal() failure\n");
exit(1);
}
FILE *fp_o;
fp_o = fopen(outKey,"wb");
fwrite(sealed,1,sizeof sealed,fp_o);
fclose(fp_o);
// Encrypt file END
const size_t outSz=sodium_base64_encoded_len(crypto_box_SEALBYTES+crypto_secretstream_xchacha20poly1305_KEYBYTES,sodium_base64_VARIANT_ORIGINAL);
char * base64Out=sodium_malloc(outSz);
sodium_bin2base64(base64Out,outSz,sealed,crypto_box_SEALBYTES+crypto_secretstream_xchacha20poly1305_KEYBYTES,sodium_base64_VARIANT_ORIGINAL);
printf("E: %s\n",base64Out);
const size_t outSzX=sodium_base64_encoded_len(crypto_secretstream_xchacha20poly1305_KEYBYTES,sodium_base64_VARIANT_ORIGINAL);
char * base64OutX=sodium_malloc(outSzX);
sodium_bin2base64(base64OutX,outSzX,key,crypto_secretstream_xchacha20poly1305_KEYBYTES,sodium_base64_VARIANT_ORIGINAL);
printf("K: %s\n",base64OutX);
目前我的PHP代码就是这样:
$keyPair=\sodium_crypto_box_keypair_from_secretkey_and_publickey(\base64_decode($privK),\base64_decode($pubK));
$ok=$sealedDataFromC;
echo $ok.PHP_EOL;
$ky2=\sodium_crypto_box_seal_open(\sodium_base642bin($ok,\SODIUM_BASE64_VARIANT_ORIGINAL),$keyPair);
echo \base64_encode($ky2).PHP_EOL;