base 64復号


今日、あるプロジェクトで160バイトのbase 64符号化された列が得られました.
char *input = "MHYCAQACIAt4ZA2cTIdqd5ik+3u1UzGfFCPgNdgKg/IxZanXTl9aAiBRI77clgTw3sDLNXrnwWp/XVF42hNFsjdoE4z018b8gAQKQywcKi/CmqDmXAIhAIS2OqlyZ46VEF/Py5zCG35MZsKcS0l1jwoA/heqWt0R";

この列を復号するために、関連base 64の復号方法をネット上で検索し、まとめると以下の2つの方法がある.
static int base64_decode(char *in, int inl, char *out, int *outl)
{
	int len=0;
	BIO *b64,*bmem;
	void *ch = NULL;
	b64=BIO_new(BIO_f_base64());
	bmem=BIO_new_mem_buf(in, inl);
	b64 = BIO_push(b64,bmem);
	*outl = 0;
	while ((len = BIO_read(b64, out, 1024)) > 0) {
		*outl += len;
	}
	out[*outl]=0;
	BIO_free_all(bmem);

	return 0;
}
static unsigned char* unbase64(char *in, int inl, int* outl)  
{  
	EVP_ENCODE_CTX  ctx;  
	int orgLen = (((inl+2)/4)*3) + 1;  
	unsigned char* orgBuf = new unsigned char[orgLen];  
	int result, tmpLen, ret;  
	EVP_DecodeInit(&ctx);  
	ret = EVP_DecodeUpdate(&ctx, (unsigned char *)orgBuf, &result, (unsigned char *)in, inl);  
	if (ret !=1) {
		return NULL;
	}
	EVP_DecodeFinal(&ctx, (unsigned char *)&orgBuf[result], &tmpLen);  
	result += tmpLen;  
	*outl = result;  
	return orgBuf;  
}  

そこで私はこのbase 64コードを上のいずれかの関数に転送し、結果は復号に失敗しました.
解析の結果,この2つの復号化方法は本質的に同じであることが分かった.すなわち,方法1(base 64_decode関数)が最終的に呼び出された方法2(unbase 64関数)のEVP_である.xxxシリーズ関数なので、エラーの原因はこれらのEVP_にまとめられています.xxx関数について、EVPを分析した.DecodeUpdateソースコードを発見し、EVP_DecodeUpdate実装には、次のコードの行があります.
/* If the current line is > 80 characters, scream alot */if (ln >= 80) { rv= -1; goto end; }
ここでln>=80は、現在解析されている行の80バイトを超えるとエラーとなる、すなわちEVP_DecodeUpdateはbase 64列を解析する際に現在の行のバイト数を規定している:80バイトを超えてはならない.
したがって、上記の160バイトのbase 64符号化を以下のように変更することができます.
char *input = "MHYCAQACIAt4ZA2cTIdqd5ik+3u1UzGfFCPgNdgKg/IxZanXTl9aAiBRI77clgTw3sDLNXrnwWp\r
/XVF42hNFsjdoE4z018b8gAQKQywcKi/CmqDmXAIhAIS2OqlyZ46VEF/Py5zCG35MZsKcS0l1jw\r
oA/heqWt0R"; 75 \r
64 //char *input = "MHYCAQACIAt4ZA2cTIdqd5ik+3u1UzGfFCPgNdgKg/IxZanXTl9aAiBRI77clgTw\r
3sDLNXrnwWp/XVF42hNFsjdoE4z018b8gAQKQywcKi/CmqDmXAIhAIS2OqlyZ46V\r
EF/Py5zCG35MZsKcS0l1jwoA/heqWt0R";

このような方法で上の2つの関数のいずれかに伝えればよい.もちろん、rを追加した後、上の2つの関数に伝わられたとき、このbase 64の長さも160+2*2=164であるべきだ.私たちは2つのリターン改行符を追加したからだ.