polarsslのRSA使用
11869 ワード
PlarSSLソースは、最もコンパクトなsslコードライブラリです.効率的で、移植と統合が容易です.特に組み込みアプリケーションに適しています.PlarSSLには対応するpem形式はなく,ベースの復号化方法のみである.
RSA関連API
1.基本データ構造
2.mpiユニット
3.RSA鍵管理
3.RSA復号化
4.RSA署名とチェック
RSAプログラミング例
出力された結果は次のとおりです.
秘密鍵pemを取得する場合の検証プログラムのデバッグ方法
1.公開鍵暗号化を検証し、秘密鍵復号使用プログラムは文字列:
符号化ファイルは
(2)秘密鍵の復号
結果:
次に、ファイルの概要に署名します.
署名されたファイルをbase 64符号化します.
次に、コード公開鍵を使用してチェックアウトを行います.
3.秘密鍵暗号化、公開鍵復号はまずファイルを暗号化する:
次に、暗号化されたファイルをbase 64符号化します.
その後、コード公開鍵を使用して復号化される.
RSA関連API
1.基本データ構造
typedef struct
{
int ver; /*!< always 0 */
size_t len; /*!< size(N) in chars */
mpi N; /*!< public modulus */
mpi E; /*!< public exponent */
mpi D; /*!< private exponent */
mpi P; /*!< 1st prime factor */
mpi Q; /*!< 2nd prime factor */
mpi DP; /*!< D % (P - 1) */
mpi DQ; /*!< D % (Q - 1) */
mpi QP; /*!< 1 / (Q % P) */
mpi RN; /*!< cached R^2 mod N */
mpi RP; /*!< cached R^2 mod P */
mpi RQ; /*!< cached R^2 mod Q */
int padding; /*!< RSA_PKCS_V15 for 1.5 padding and
RSA_PKCS_v21 for OAEP/PSS */
int hash_id; /*!< Hash identifier of md_type_t as
specified in the md.h header file
for the EME-OAEP and EMSA-PSS
encoding */
}
rsa_context;
2.mpiユニット
// mpi
void mpi_init( mpi *X );
// mpi
void mpi_free( mpi *X );
// mpi
int mpi_grow( mpi *X, size_t nblimbs );
// mpi
int mpi_copy( mpi *X, const mpi *Y );
// mpi
void mpi_swap( mpi *X, mpi *Y );
// int mpi
int mpi_lset( mpi *X, t_sint z );
// mpi
int mpi_get_bit( const mpi *X, size_t pos );
// 0 mpi
size_t mpi_lsb( const mpi *X );
// mpi
size_t mpi_msb( const mpi *X );
// mpi
size_t mpi_size( const mpi *X );
// mpi
int mpi_read_string( mpi *X, int radix, const char *s );
// mpi
int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
3.RSA鍵管理
// rsa , padding, padding==RSA_PKCS_V15,hash_id
void rsa_init( rsa_context *ctx, int padding, int hash_id);
// rsa
int rsa_gen_key( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
unsigned int nbits, int exponent );
//
int rsa_check_pubkey( const rsa_context *ctx );
//
int rsa_check_privkey( const rsa_context *ctx );
3.RSA復号化
/* PKCS#1
* \param ctx RSA
* \param f_rng
* \param p_rng
* \param mode RSA_PUBLIC RSA_PRIVATE
* \param ilen
* \param input
* \param output
*
* \return 0
*/
int rsa_pkcs1_encrypt( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode, size_t ilen,
const unsigned char *input,
unsigned char *output );
/*
* \param ctx RSA
* \param mode RSA_PUBLIC RSA_PRIVATE
* \param olen
* \param input
* \param output
* \param output_max_len
*
* \return 0
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len );
4.RSA署名とチェック
/** PKCS#1 , rsa
* \param ctx RSA
* \param f_rng
* \param p_rng
* \param mode RSA_PUBLIC RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen
* \param hash
* \param sig
*
* \return 0
*/
int rsa_pkcs1_sign( rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
/** PKCS#1 ,
* \param ctx rsa
* \param mode RSA_PUBLIC RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen
* \param hash
* \param sig
*
* \return 0
*/
int rsa_pkcs1_verify( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
RSAプログラミング例
#define KEY_LEN 128
#define RSA_N "9292758453063D803DD603D5E777D788" \
"8ED1D5BF35786190FA2F23EBC0848AEA" \
"DDA92CA6C3D80B32C4D109BE0F36D6AE" \
"7130B9CED7ACDF54CFC7555AC14EEBAB" \
"93A89813FBF3C4F8066D2D800F7C38A8" \
"1AE31942917403FF4946B0A83D3D3E05" \
"EE57C6F5F5606FB5D4BC6CD34EE0801A" \
"5E94BB77B07507233A0BC7BAC8F90F79"
#define RSA_E "10001"
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
"66CA472BC44D253102F8B4A9D3BFA750" \
"91386C0077937FE33FA3252D28855837" \
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
"DF79C5CE07EE72C7F123142198164234" \
"CABB724CF78B8173B9F880FC86322407" \
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
"071513A1E85B5DFA031F21ECAE91A34D"
#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
"2C01CAD19EA484A87EA4377637E75500" \
"FCB2005C5C7DD6EC4AC023CDA285D796" \
"C3D9E75E1EFC42488BB4F1D13AC30A57"
#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
"910E4168387E3C30AA1E00C339A79508" \
"8452DD96A9A5EA5D9DCA68DA636032AF"
#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
"3C94D22288ACD763FD8E5600ED4A702D" \
"F84198A5F06C2E72236AE490C93F07F8" \
"3CC559CD27BC2D1CA488811730BB5725"
#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
"D8AAEA56749EA28623272E4F7D0592AF" \
"7C1F1313CAC9471B5C523BFE592F517B" \
"407A1BD76C164B93DA2D32A383E58357"
#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
"F38D18D2B2F0E2DD275AA977E2BF4411" \
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
"A74206CEC169D74BF5A8C50D6F48EA08"
#define PT_LEN 10
#define RSA_PT "helo rsa"
static int myrand(void *rng_state, unsigned char *output, size_t len) {
size_t i;
if (rng_state != NULL)
rng_state = NULL;
for (i = 0; i < len; ++i)
output[i] = rand();
return (0);
}
/*
* Checkup routine
*/
int rsa_self_test(int verbose) {
size_t len;
rsa_context rsa;
unsigned char rsa_plaintext[PT_LEN];
unsigned char rsa_decrypted[PT_LEN];
unsigned char rsa_ciphertext[KEY_LEN];
#if defined(POLARSSL_SHA1_C)
unsigned char sha1sum[20];
#endif
rsa_init(&rsa, RSA_PKCS_V15, 0);
rsa.len = KEY_LEN;
mpi_read_string(&rsa.N, 16, RSA_N);
mpi_read_string(&rsa.E, 16, RSA_E);
mpi_read_string(&rsa.D, 16, RSA_D);
mpi_read_string(&rsa.P, 16, RSA_P);
mpi_read_string(&rsa.Q, 16, RSA_Q);
mpi_read_string(&rsa.DP, 16, RSA_DP);
mpi_read_string(&rsa.DQ, 16, RSA_DQ);
mpi_read_string(&rsa.QP, 16, RSA_QP);
printf("RSA Test
");
if (verbose != 0)
printf(" RSA key validation: ");
if (rsa_check_pubkey(&rsa) != 0 || rsa_check_privkey(&rsa) != 0) {
if (verbose != 0)
printf("failed
");
return (1);
}
memcpy(rsa_plaintext, RSA_PT, PT_LEN);
printf("
:%s
", rsa_plaintext);
if (verbose != 0)
printf("passed
PKCS#1 encryption : ");
if (rsa_pkcs1_encrypt(&rsa, &myrand, NULL, RSA_PUBLIC, PT_LEN, rsa_plaintext, rsa_ciphertext) != 0) {
if (verbose != 0)
printf("failed
");
return (1);
}
if (verbose != 0)
printf("passed
PKCS#1 decryption : ");
if (rsa_pkcs1_decrypt(&rsa, RSA_PRIVATE, &len, rsa_ciphertext, rsa_decrypted, sizeof(rsa_decrypted)) != 0) {
if (verbose != 0)
printf("failed
");
return (1);
}
if (memcmp(rsa_decrypted, rsa_plaintext, len) != 0) {
if (verbose != 0)
printf("failed
");
return (1);
}
printf("
:%s
", rsa_decrypted);
#if defined(POLARSSL_SHA1_C)
if (verbose != 0)
printf("passed
PKCS#1 data sign : ");
sha1(rsa_plaintext, PT_LEN, sha1sum);
if (rsa_pkcs1_sign(&rsa, NULL, NULL, RSA_PRIVATE, SIG_RSA_SHA1, 20, sha1sum, rsa_ciphertext) != 0) {
if (verbose != 0)
printf("failed
");
return (1);
}
if (verbose != 0)
printf("passed
PKCS#1 sig. verify: ");
if (rsa_pkcs1_verify(&rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20, sha1sum, rsa_ciphertext) != 0) {
if (verbose != 0)
printf("failed
");
return (1);
}
if (verbose != 0)
printf("passed
");
#endif /* POLARSSL_SHA1_C */
rsa_free(&rsa);
return (0);
}
出力された結果は次のとおりです.
RSA Test
RSA key validation:
:helo rsa
passed
PKCS#1 encryption : passed
PKCS#1 decryption :
:helo rsa
passed
PKCS#1 data sign : passed
PKCS#1 sig. verify: passed
秘密鍵pemを取得する場合の検証プログラムのデバッグ方法
1.公開鍵暗号化を検証し、秘密鍵復号使用プログラムは文字列:
helo rsa
フィールドを暗号化し、暗号化後base 64符号化に変換する.結果: :
helo rsa
:
NogGOEbfZ7YZn1G+8GO82MPXxWVYO964187G1ZhdYq1bS3Lvit2IRP66UFY9/ffSW2Ck1HN0BQ/mhwkTQRWnmdvby15amOnV6/XABEYAz0156ai1klpocCoFNqHwwO498gp3tSUUW0ULPgpPtXdWK8jkNAgALhasg7wHKXOk1p/xgSWtDPj+7LqZ45ooKCcA+xMbMXeYH1hs0zsFzp842rVWAThj5TBIhG0xfY80hKPrsAXDiOe19OUJf0+uZbSrI/so3yiI2mnosgfq12Srw5JFl9X3wDI+lKA3xOO1dcDYNbfpacPzaRRz/vxr0ZJJ67Uc5i+48/BFqTUPc+dcUw==
符号化ファイルは
rsa_encrypt_encode.txt
ファイルに格納される.(1)base 64復号動作base64 -d rsa_encrypt_encode.txt > rsa_encrypt.txt
(2)秘密鍵の復号
openssl rsautl -decrypt -in rsa_encrypt.txt -inkey rsa_pri.key -out rsa_decrypt.txt
結果:
helo rsa
2.検証公開鍵チェックは、まずファイルの要約を取得し、長さは40文字である.$ openssl dgst -sha1 file.txt
SHA1(file.txt)= 52b60977ce28dd6c0c6f096f722d9d9fbaba0dd5
次に、ファイルの概要に署名します.
$ openssl dgst -sha1 -sign rsa_pri_2048.key -out sign_file.txt file.txt
署名されたファイルをbase 64符号化します.
$ base64 sign_file.txt > sign_file_base64.txt
次に、コード公開鍵を使用してチェックアウトを行います.
3.秘密鍵暗号化、公開鍵復号はまずファイルを暗号化する:
$ openssl rsautl -encrypt -in rsa_decrypt.txt -inkey rsa_pri_2048.pem -out rsa_encrypt.txt
次に、暗号化されたファイルをbase 64符号化します.
$ base64 rsa_encrypt.txt > rsa_encrypt_base64.txt
その後、コード公開鍵を使用して復号化される.