はじめまして。
ある暗号化されたファイルを複合化するために、複合キーというのを用いて複合するようです。
今回は、暗号化されたファイルを複合するプログラムを教えていただきました。
このプログラムとまったく逆の作業をして、複合化されたファイルを暗号化するプログラムを作ることはかのうでしょうか?
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <windows.h>
#include <wincrypt.h>
#include <winsock.h>
#define VER "0.1"
#define KEY "ectGameMon"
#define SIGN1 0x32812622
#define SIGN2 0x32812621
#define PUBKEY "\x06\x02\x00\x00\x00\x24\x00\x00\x52\x53\x41\x31\x00\x02\x00\x00" \
"\x01\x00\x01\x00\xFB\xE3\xFC\x09\xAF\xAE\x65\x8C\x96\x4C\xC5\x37" \
"\xD2\xA4\x77\xE7\x4C\x41\xC2\xCF\xF2\xFE\x2D\x9C\x80\x94\x0C\x88" \
"\x6D\xB3\x84\x9F\x8C\x22\xA0\xC9\xCD\xC0\xAB\x30\x65\x82\x42\x3C" \
"\xEE\x3C\xA8\xB7\x11\xD6\x22\xFA\xFB\x23\xF7\x72\xCD\xE7\xD0\x6F" \
"\x6A\x8E\x96\xE3"
void std_err(int type);
int main(int argc, char *argv[/url]) {
FILE *fd;
struct stat xstat;
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD len;
u_int buffsz;
u_char *buff,
*input,
*output,
*filename,
*signature;
struct gameguard_header {
u_int sign1;
u_int filename_size;
u_int signature_size;
u_int sign2;
} *gh = NULL;
setbuf(stdout, NULL);
fputs("\n"
"GameGuard files decrypter "VER"\n"
"by Luigi Auriemma\n"
"e-mail: aluigi@autistici.org\n"
"web: aluigi.org\n"
"\n", stdout);
if(argc < 3) {
printf("\n"
"Usage: %s <input_file> <output_file>\n"
"\n", argv[0]);
exit(1);
}
input = argv[1];
output = argv[2];
printf("- open input file: %s\n", input);
fd = fopen(input, "rb");
if(!fd) std_err(0);
fstat(fileno(fd), &xstat);
buffsz = xstat.st_size;
printf(" filesize: %u\n", buffsz);
buff = malloc(buffsz);
if(!buff) std_err(0);
len = fread(buff, 1, buffsz, fd);
fclose(fd);
len -= sizeof(struct gameguard_header);
gh = (struct gameguard_header *)(buff + len);
len -= (gh->filename_size + gh->signature_size);
if((gh->sign1 != SIGN1) ||
(gh->sign2 != SIGN2)) {
printf("\n"
"Alert: the signs in the file don't match the default signs, I try to continue:\n"
" 0x%08x (should be 0x%08x) and 0x%08x (should be 0x%08x)\n"
"\n",
gh->sign1, SIGN1,
gh->sign2, SIGN2);
}
filename = buff + len;
printf("- built-in filename: %s\n", filename);
signature = buff + len + gh->filename_size;
if(!CryptAcquireContext(
&hProv,
NULL,
MS_DEF_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) std_err(1);
/* VERIFY SIGNATURE */
fputs("- verify signature:", stdout);
if(!CryptCreateHash(
hProv,
CALG_MD5,
0,
0,
&hHash)) std_err(1);
if(!CryptImportKey(
hProv,
PUBKEY,
sizeof(PUBKEY) - 1,
0,
0,
&hKey)) std_err(1);
if(!CryptHashData(
hHash,
buff,
len + gh->filename_size,
0)) std_err(1);
if(!CryptVerifySignature(
hHash,
signature,
gh->signature_size,
hKey,
NULL,
0)) {
fputs(" WRONG!\n", stdout);
} else {
fputs(" OK\n", stdout);
}
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
/* DECRYPT DATA */
if(!CryptCreateHash(
hProv,
CALG_MD5,
0,
0,
&hHash)) std_err(1);
if(!CryptHashData(
hHash,
KEY,
sizeof(KEY) - 1,
0)) std_err(1);
if(!CryptDeriveKey(
hProv,
CALG_RC4,
hHash,
0,
&hKey)) std_err(1);
if(!CryptDecrypt(
hKey,
0,
TRUE,
0,
buff,
&len)) std_err(1);
printf("- write output file: %s\n", output);
fd = fopen(output, "wb");
if(!fd) std_err(0);
fwrite(buff, len, 1, fd);
fclose(fd);
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
free(buff);
fputs("- Finished\n", stdout);
return(0);
}
void std_err(int type) {
if(type) {
printf("\n"
"Error: error during the usage of the cryptography (0x%lx)\n"
" If you received a sign error before means this is not a valid GameGuard\n"
" INI file\n"
"\n", GetLastError());
} else {
perror("\nError");
}
exit(1);
}
実際に暗号化されたファイルと複合化されたファイルを添付します。
よろしければ教えてください。
Cryptでの複合化 暗号化
Re:Cryptでの複合化 暗号化
> このプログラムとまったく逆の作業をして、複合化されたファイルを暗号化するプログラムを作ることはかのうでしょうか?
PUBKEYで暗号化することはできると思いますが、
復号するには、PUBKEYと対となる鍵が必要です。
PUBKEYで暗号化することはできると思いますが、
復号するには、PUBKEYと対となる鍵が必要です。
Re:Cryptでの複合化 暗号化
>PUBKEYで暗号化することはできると思いますが、
>復号するには、PUBKEYと対となる鍵が必要です。
あれ、逆じゃないですか?
暗号化されたデータの提供元の秘密鍵が分からないので無理そうですよね。
>復号するには、PUBKEYと対となる鍵が必要です。
あれ、逆じゃないですか?
暗号化されたデータの提供元の秘密鍵が分からないので無理そうですよね。
Re:Cryptでの複合化 暗号化
回答ありがとうございます。
>と思って少し試してみたのですけど、データ部分はできても、全く同じ署名を付けるのが無理そうな感じですね・・・。
まったく同じ署名をつけるのは無理、とありますが、なんででしょうか・・
>PUBKEYで暗号化することはできると思いますが、
復号するには、PUBKEYと対となる鍵が必要です。
つまり、暗号キーと複合キーという両方が必要なのでしょうか?
>と思って少し試してみたのですけど、データ部分はできても、全く同じ署名を付けるのが無理そうな感じですね・・・。
まったく同じ署名をつけるのは無理、とありますが、なんででしょうか・・
>PUBKEYで暗号化することはできると思いますが、
復号するには、PUBKEYと対となる鍵が必要です。
つまり、暗号キーと複合キーという両方が必要なのでしょうか?
Re:Cryptでの複合化 暗号化
回答ありがとうございます。
>と思って少し試してみたのですけど、データ部分はできても、全く同じ署名を付けるのが無理そうな感じですね・・・。
まったく同じ署名をつけるのは無理、とありますが、なんででしょうか・・
>PUBKEYで暗号化することはできると思いますが、
復号するには、PUBKEYと対となる鍵が必要です。
つまり、暗号キーと複合キーという両方が必要なのでしょうか?
>と思って少し試してみたのですけど、データ部分はできても、全く同じ署名を付けるのが無理そうな感じですね・・・。
まったく同じ署名をつけるのは無理、とありますが、なんででしょうか・・
>PUBKEYで暗号化することはできると思いますが、
復号するには、PUBKEYと対となる鍵が必要です。
つまり、暗号キーと複合キーという両方が必要なのでしょうか?
Re:Cryptでの複合化 暗号化
対称鍵の暗号 (e.g. DES) の場合,暗号鍵と復号鍵は同じ物を使います。
非対称鍵の暗号 (e.g. RSA) の場合,暗号鍵と復号鍵は別の物を使います。
今回の場合,RSAのようですから,暗号鍵 (公開鍵) と復号鍵 (秘密鍵) は別の物になります。
・メッセージを暗号化する場合は,送信者は受信者の公開鍵で暗号化して送信し,受信者は自身の秘密鍵で復号する
・メッセージに署名をする場合は,送信者は自身の秘密鍵でメッセージダイジェストを暗号化して送信し,受信者は送信者の公開鍵で復号して検証する
RSAをはじめとした公開鍵暗号方式では,公開鍵と秘密鍵のペアが必ず存在します。
# 片方だけでは暗号化できないか,復号できないか,だれでも復号できるかのどれかになる。
断片だけを見ても何をしたいのかがわからないのですが,
・送信者は自身の秘密鍵 (署名用) と受信者の公開鍵 (暗号用) が必要
・受信者は送信者の公開鍵 (署名検証用)と自身の秘密鍵 (復号用) が必要
であって,秘密鍵は公開してはならないのですから,他人が暗号化したデータに対して,
> 全く同じ署名を付けるのが無理
ということになります。
暗号回りに関しては,結城浩氏の著書
Site: 『新版暗号技術入門――秘密の国のアリス』
http://www.hyuki.com/cr/index.html
が分かり易くて良いと思います。
ちなみに,複合キーではSQLにおける複数列からなる主キーの意味になってしまいますよ。
非対称鍵の暗号 (e.g. RSA) の場合,暗号鍵と復号鍵は別の物を使います。
今回の場合,RSAのようですから,暗号鍵 (公開鍵) と復号鍵 (秘密鍵) は別の物になります。
・メッセージを暗号化する場合は,送信者は受信者の公開鍵で暗号化して送信し,受信者は自身の秘密鍵で復号する
・メッセージに署名をする場合は,送信者は自身の秘密鍵でメッセージダイジェストを暗号化して送信し,受信者は送信者の公開鍵で復号して検証する
RSAをはじめとした公開鍵暗号方式では,公開鍵と秘密鍵のペアが必ず存在します。
# 片方だけでは暗号化できないか,復号できないか,だれでも復号できるかのどれかになる。
断片だけを見ても何をしたいのかがわからないのですが,
・送信者は自身の秘密鍵 (署名用) と受信者の公開鍵 (暗号用) が必要
・受信者は送信者の公開鍵 (署名検証用)と自身の秘密鍵 (復号用) が必要
であって,秘密鍵は公開してはならないのですから,他人が暗号化したデータに対して,
> 全く同じ署名を付けるのが無理
ということになります。
暗号回りに関しては,結城浩氏の著書
Site: 『新版暗号技術入門――秘密の国のアリス』
http://www.hyuki.com/cr/index.html
が分かり易くて良いと思います。
ちなみに,複合キーではSQLにおける複数列からなる主キーの意味になってしまいますよ。