ã»ãã¥ãªãã£äžéèŠãªã³ãŒãã®äžéšã«å¯Ÿããã³ã³ãã€ã©ã®æ¹ãããé²æ¢
åé¡
äžéšã®ã³ã³ãã€ã©ã¯ã圹ã«ç«ããªããšèããããæäœãæé©åããŸãã
ããšãã°ãã³ã³ãã€ã©MS Visual C ++ã¯æŒç®å| memset |ãèŠã€ããŸããã 次ã®Torå¿åãããã¯ãŒã¯å®è£ ã³ãŒãã®ã¹ããããïŒ
int crypto_pk_private_sign_digest(...) { char digest[DIGEST_LEN]; (...) memset(digest, 0, sizeof(digest)); return r; }
ãã ãããã®æŒç®åã®åœ¹å²| memset | |ãã€ãžã§ã¹ã|ãããã¡ãã¯ãªã¢ããããšã§ã æ©å¯ããŒã¿ãããåæåãããŠããªãã¹ã¿ãã¯ããã®ããŒã¿ã®åŸç¶ã®èªã¿åãã§ã¯ãæ©å¯æ å ±ãååŸããããšã¯äžå¯èœã§ããã
äžéšã®ã³ã³ãã€ã©ã¯ãããã°ã©ã ã®ã©ããã§ã³ãŒããééã£ãŠãããšèããŠãæ¡ä»¶ä»ããã§ãã¯ãåé€ã§ãããšèããŠããŸãã ããšãã°ã次ã®ã³ãŒãã¹ãããããèŠã€ãã
call_fn(ptr); // ptr. // if (ptr == NULL) { error("ptr must not be NULL"); }
äžéšã®ã³ã³ãã€ã©ã¯ãæ¡ä»¶| ptr == NULL | ããã§ãªããã°ãé¢æ°| call_fnïŒïŒ|ã§ãããéæ¥åç §ããã®ã¯ééã£ãŠããã®ã§ãåžžã«FALSEã§ãªããã°ãªããŸããã
解決ç
ã³ã³ãã€ã«ãããã³ãŒããåæãããã¹ãŠã®åœä»€ãããã«ååšããããšã確èªããŸãã ïŒããã¯æšæºãµã€ãºã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯äžå¯èœã§ãããã»ãã¥ãªãã£ã®èŠ³ç¹ããéèŠãªã³ãŒãã«å¯ŸããŠã¯å®è¡ããå¿ èŠããããŸãïŒã
ã³ã³ãã€ã©ãå®è¡ã§ããæé©åãç解ããå®å šãªããã°ã©ãã³ã°ã®ååã®èŠ³ç¹ããããããã®å¹æãæ éã«è©äŸ¡ããŸãã ç¹ã«ãã³ãŒããã©ã°ã¡ã³ããŸãã¯ãã©ã³ããåé€ããæé©åãããã³ããã°ã©ã ã®æ®ãã®éšåãæ£ããå Žåã«ã衚瀺ãããªãããšã©ãŒãé²æ¢ããã³ãŒããã©ã°ã¡ã³ãã«æ³šæããŠãã ããã
å¯èœãªéããã³ã³ãã€ã«äžã«ãã®æé©åãç¡å¹ã«ããŠãã»ãã¥ãªãã£ã«åœ±é¿ããæ¡ä»¶ã®æ€èšŒãåé€ãŸãã¯åŒ±ããããšãæ€èšããŠãã ããã
æé©åã«ããåœä»€ã®åé€ãé²ãããã«ãvolatileããŒã¯ãŒãã䜿çšããŠé¢æ°ããªãŒããŒã©ã€ãã§ããŸãã ããã¯ãããšãã°memset |ããªãŒããŒã©ã€ããããšãã«libotteryã§äœ¿çšãããŸãã
void * (*volatile memset_volatile)(void *, int, size_t) = memset;
memset_sã®åŒã³åºãã¯C11ã§å°å ¥ãããŠãããæé©åäžã®åé€ã¯çŠæ¢ãããŠããŸãã
#define __STDC_WANT_LIB_EXT1__ 1 #include <string.h> ... memset_s(secret, sizeof(secret), 0, sizeof(secret));
å®å šãªããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ãšå®å šã§ãªãããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ã®æ··åãé¿ãã
åé¡
å€ãã®ããã°ã©ãã³ã°ç°å¢ã¯ãåããœãããŠã§ã¢ã€ã³ã¿ãŒãã§ã€ã¹ã®ç°ãªãå®è£ ãæäŸããŸããæ©èœã¯å€èŠçã«ã¯åãã§ãããã»ãã¥ãªãã£æ©èœã¯æ ¹æ¬çã«ç°ãªããŸãã
ãã®åé¡ã¯ãä¹±æ°ã»ã³ãµãŒã®å žåçãªãã®ã§ãïŒOpenSSLã«ã¯| RAND_bytesïŒïŒ|ããããŸãã ããã³| RAND_pseudo_bytesïŒïŒ| BSD Cã©ã€ãã©ãªã«ã¯| RAND_bytesïŒïŒ| ããã³| RAND_pseudo_bytesïŒïŒ|ãJavaã§-| SecureRandom | ããã³|ã©ã³ãã |
ãã1ã€ã®äŸã¯ãæéã«äŸåããªããã€ãã¯ãŒãæ¯èŒæ©èœãæäŸããã·ã¹ãã ã«ã¯ãåæã«ã¿ã€ã ãªãŒã¯ãåŒãèµ·ããå¯èœæ§ã®ãããªãã·ã§ã³ããããšããäºå®ã§ãã
æªã決æ
æ©èœã¯ãäžéšã®ãã©ãããã©ãŒã ã§ã¯å®å šã§ãä»ã®ãã©ãããã©ãŒã ã§ã¯å±éºãªå ŽåããããŸãã ãã®ãããªå Žåãããã°ã©ããŒã¯ãã®é¢æ°ã䜿çšããŠãèªåã®ã³ãŒããå®å šãªãã©ãããã©ãŒã ã§å®è¡ããããšä¿¡ããŠããŸãã ã³ãŒããä»ã®ãã©ãããã©ãŒã ã«ç§»æ€ãããŠå®å šã§ãªããªãå¯èœæ§ããããããããã¯æªãã¢ãããŒãã§ã-誰ãæ°ä»ããªãã§ãããã
ãã©ãããã©ãŒã äŸåã®é¢æ°ãåå®çŸ©ã§ããã·ã¹ãã ã§ã¯ãäžéšã®ããã°ã©ããŒã¯å®å šã§ãªãé¢æ°ãå®å šãªãã®ãšããŠãªãŒããŒã©ã€ãããäžè¬ã«å®å šã§ã¯ãªãããã°ã©ã ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠããã°ã©ã ãèšè¿°ããŸãã ããã¯ãããã°ã©ããŒãå®å šã§ãªãããã«èŠããã³ãŒããæžããšããäºå®ã«ã€ãªãããããããªãè°è«ã®äœå°ã®ããã¢ãããŒãã§ãã ããã«ããªãŒããŒã©ã€ããããã¡ãœãããæ©èœããªãå Žåãããã°ã©ã ã¯å®å šã§ãªããªãããããå€å¥ã§ããŸããã ãããŠæåŸã«ãããã¯ããã®ãããªããã°ã©ã ã®ã³ãŒãæçãä»ã®ãããžã§ã¯ãã«ã³ããŒãããå Žåãå®å šã§ãªããšããäºå®ã«ã€ãªãããŸãã
解決ç
å¯èœãªéããå®å šãªæ©èœã«å®å šã§ãªããªãã·ã§ã³ã䜿çšããªãã§ãã ããã ããšãã°ãã©ã³ãã ãªåæããã£ã³ã°ã䜿çšããå ç¢ãªã¹ããªãŒã æå·ã«åºã¥ãMIFã¯ãã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã§ååã«é«éã§ãã ããŒã¿åã«äŸåããªãmemcmpã®çœ®æã¯ããã¹ãŠã®ã¡ã¢ãªé åæ¯èŒæäœã«äœ¿çšã§ããã»ã©é«éã§ãã
å®å šã§ãªãé¢æ°ãåé€ã§ããªãå Žåã¯ãã³ã³ãã€ã«æ®µéã§ãšã©ãŒãçæãããããã«åå®çŸ©ããããéçã³ãŒãåæçšã®ããŒã«ã䜿çšããŠãå®å šã§ãªãé¢æ°ã®äœ¿çšãç¹å®ããŠèŠåããŸãã å®å šã§ãªããªãã·ã§ã³ãå®å šãªãªãã·ã§ã³ãšããŠãªãŒããŒã©ã€ãã§ããå Žåã¯ãã»ãã¥ãªãã£ã匷åããããã«ãå®å šã§ãªãAPIãåŒã³åºããªãã§ããã®äœ¿çšã®äºå®ãæ€åºã§ããããšã確èªããŠãã ããã
äž¡æ¹ã®ãªãã·ã§ã³ïŒå®å šãªãã®ãšå®å šã§ãªããã®ïŒãæ®ãå¿ èŠãããå Žåã¯ãé¢æ°åãéåžžã«ç°ãªãã誀ã£ãŠå®å šã§ãªããªãã·ã§ã³ã䜿çšããã®ãå°é£ã§ããããšã確èªããŠãã ããã ããšãã°ãå®å šãªMAPãšå®å šã§ãªãMAPãããå Žåãå®å šã§ãªããªãã·ã§ã³ã«ãRandomãããFastRandomãããMersenneTwisterãããŸãã¯ãLCGRandããšããååãä»ããªãã§ãã ããã代ããã«ããInsecureRandomããªã©ã®ååãä»ããŸãã å®å šã§ãªãé¢æ°ã®äœ¿çšãåžžã«å°ãæãããã«ãããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ãèšèšããŸãã
ãã©ãããã©ãŒã ãå®å šã§ãªãããšã瀺ãååã®ãªãé¢æ°ã®å®å šã§ãªãããŒãžã§ã³ãæäŸãããã®é¢æ°ãåé€ã§ããªãå Žåã¯ãå®å šãªååã®ã·ã¹ãã ã³ãŒã«ã©ãããŒã䜿çšããã³ãŒãã®éçåæã«ãããå®å šã§ãªãååã®ãã¹ãŠã®äœ¿çšãæããã«ããŸãã
é¢æ°ãäžéšã®ãã©ãããã©ãŒã ã§ã¯å®å šã§ãä»ã®ãã©ãããã©ãŒã ã§ã¯å®å šã§ãªãå Žåã¯ãé¢æ°ãçŽæ¥äœ¿çšããªãã§ãã ããã代ããã«ãå®å šãªã©ãããŒãå®çŸ©ããŠäœ¿çšããŠãã ããã
åãAPIã¬ãã«ã§ã»ãã¥ãªãã£ã¬ã€ã€ãŒãšæå·åããªããã£ãã®æœè±¡åãæ··åšãããªãã§ãã ãã
åé¡
ãœãããŠã§ã¢ã€ã³ã¿ãŒãã§ã€ã¹ã®ããŸããŸãªéšåã«å¿ èŠãªåæã®çš®é¡ãæ確ã§ãªãå Žåãããã°ã©ãã¯å®å šã«äœ¿çšã§ããæ©èœã«ã€ããŠååã«ç°¡åã«ééããç¯ãå¯èœæ§ããããŸãã
RSAãœãããŠã§ã¢ã€ã³ã¿ãŒãã§ãŒã¹ã®æ¬¡ã®äŸïŒçºæãããããå®éã«èŠããããã®ã«äŒŒãŠããïŒãæ€èšããŠãã ããã
enum rsa_padding_t { no_padding, pkcs1v15_padding, oaep_sha1_padding, pss_padding }; int do_rsa(struct rsa_key *key, int encrypt, int public, enum rsa_padding_t padding_type, uint8_t *input, uint8_t *output);
ãããŒããã©ã¡ãŒã¿ã«è©³çŽ°ã®ã³ã³ããŒãã³ããå«ãŸããŠãããšä»®å®ãããšãé¢æ°ã¯16éãã®æ¹æ³ã§åŒã³åºãããšãã§ãããã®å€ãã¯ç¡æå³ã§ãäžéšã¯å®å šã§ã¯ãããŸããã
æå·å/埩å·å | 察称/é察称
| ããã£ã³ã°ã¿ã€ã
| çºèš |
---|---|---|---|
0 | 0 | ãªã | ããã£ã³ã°ãªãã®åŸ©å·åã åœç©ã®å¯èœæ§ã |
0 | 0 | pkcs1v15 | 埩å·åPKCS1 v1.5ã ãããããBlainbacherã«ããæ»æã®å¯Ÿè±¡ãšãªããŸãã |
0 | 0 | ãã | 埩å·åOAEPã è¯ããªãã·ã§ã³ã |
0 | 0 | pss | 埩å·åPSSã æå³ããªããšã©ãŒã«ã€ãªããå¯èœæ§ããããããªãå¥åŠãªãªãã·ã§ã³ |
0 | 1 | ãªã | ããã£ã³ã°ãªãã®çœ²åã åœç©ã®å¯èœæ§ã |
0 | 1 | pkcs1v15 | 眲åPKCS1 v1.5ã äžéšã®ã¢ããªã±ãŒã·ã§ã³ã«é©ããŠããŸãããPSS眲åã䜿çšããããšããå§ãããŸãã |
0 | 1 | ãã | 眲åOAEPã äžéšã®ã¢ããªã±ãŒã·ã§ã³ã«é©ããŠããŸãããPSS眲åã䜿çšããããšããå§ãããŸãã |
0 | 1 | pss | 眲åPSSã éåžžã«è¯ããªãã·ã§ã³ã |
... | ... | ... | æ®ãã®ãªãã·ã§ã³ïŒæå·åãšçœ²åã®æ€èšŒïŒã |
ãã®é¢æ°ãåŒã³åºã16ã®å¯èœãªæ¹æ³ã®ãã¡4ã€ã ããå®å šã§ãå¥ã®6ã€ã¯å®å šã§ã¯ãªããå Žåã«ãã£ãŠã¯æ®ãã®6ã€ã䜿çšäžã«åé¡ãåŒãèµ·ããå¯èœæ§ãããããšã«æ³šæããŠãã ããã ãã®ãããªAPIã¯ãRSAã·ã¹ãã ã§ããŸããŸãªè¿œå ã¡ãœããã䜿çšããããšã®æå³ãç解ããŠããéçºè ã«ã®ã¿é©ããŠããŸãã
ããã§ãããŸããŸãªã¢ãŒãã§ã®ãããã¯æå·åãããŒçæãããŸããŸãªã¡ãã»ãŒãžèªèšŒã³ãŒãããã³çœ²åçšã®ããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ãè¿œå ããããšãæ³åããŠãã ããã ãã®ãããªããã°ã©ã ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠèªèšŒãšããŒã¿æå·åãå®è£ ããæ£ããæ©èœãéçºããããšããããã°ã©ããŒã«ã¯ãèšå€§ãªéžæè¢ããããŸãããå®å šãªãªãã·ã§ã³ã®æ°ã¯æããã«æžå°ããŸãã
解決ç
- é«ã¬ãã«ã®ããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããŸãã ããšãã°ã匷åãªã¢ã«ãŽãªãºã ã®ã¿ãå®å
šã«äœ¿çšããããŒã¿ã®æå·åãšèªèšŒãå®è£
ããæ©èœãæäŸããŸãã 察称ããã³é察称ã¢ã«ãŽãªãºã ãšãã®åäœã¢ãŒãã®ããŸããŸãªçµã¿åãããæäŸããé¢æ°ãäœæããå Žåããã®é¢æ°ãå®å
šã§ãªãã¢ã«ãŽãªãºã ãšãã®å®å
šã§ãªãçµã¿åããã®äœ¿çšãèš±å¯ããªãããšã確èªããŠãã ããã
- å¯èœãªéããäœã¬ãã«APIãé¿ããŠãã ããã ã»ãšãã©ã®ãŠãŒã¶ãŒã¯ãããã£ã³ã°ãªãã§RSAã䜿çšããããECBã¢ãŒãã§ãããã¯æå·ã䜿çšãããããŠãŒã¶ãŒãéžæããã©ã³ãã å€ã§DSA眲åã䜿çšãããããå¿
èŠã¯ãããŸããã ãããã®é¢æ°ã¯ãæ°žç¶çãªãã®ãå®çŸããããã®ãã«ãã£ã³ã°ãããã¯ãšããŠäœ¿çšã§ããŸããããšãã°ãè¿œå ãªãã§RSAãåŒã³åºãåã«OAEPããã£ã³ã°ãè¡ãããããã¯1ã2ã3ã«å¯ŸããŠECBã¢ãŒãã§æå·åã䜿çšããŠ...ã©ã³ãã DSAå€ã«ã©ã³ãã ãŸãã¯äºæž¬äžå¯èœãªãã€ãã·ãŒã±ã³ã¹ã䜿çšããŸãããå®éã«ã¯ãæ£ãããªãå Žåããã誀ã£ãŠäœ¿çšãããé »åºŠãé«ãããšã瀺ãããŠããŸãã
ç¹å®ã®ãããã³ã«ã®å®è£ ã«ã¯ä»ã®ããã€ãã®ããªããã£ããå¿ èŠã§ãããæ°ãããããã³ã«ã®å®è£ ã«ã¯ããããé©ããªãã§ãããã ããšãã°ãCBCãPKCS1 v1.5ãããã³RC4ã䜿çšããã«ãã©ãŠã¶ãŒäºæã®TLSãå®è£ ããããšã¯ã§ããŸãããããããã®ããªããã£ãã¯ããããé©åãªãªãã·ã§ã³ã§ã¯ãããŸããã
çµéšã®æµ ãããã°ã©ããŒã䜿çšããæå·åã¢ãžã¥ãŒã«ãæäŸããå Žåã¯ããã®ãããªé¢æ°ãå®å šã«é¿ããŠãååã«èª¬æãããé«ã¬ãã«ã®å®å šãªæäœãå®è£ ããé¢æ°ã®ã¿ãéžæããããšããå§ãããŸãã
- çµéšã®ãããŠãŒã¶ãŒãšçµéšã®æµ
ããŠãŒã¶ãŒã®äž¡æ¹ã«ã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããå¿
èŠãããå Žåã¯ãé«ã¬ãã«ãšäœã¬ãã«ã®ãœãããŠã§ã¢ã€ã³ã¿ãŒãã§ãŒã¹ãæ確ã«åé¢ããŠãã ããã ãå®å
šãªæå·åãæ©èœã¯ããããã«å€æŽãããåŒæ°ãæã€ãäžæ£ãªæå·åããšåãæ©èœã§ãã£ãŠã¯ãªããŸããã é¢æ°ãšåãããã±ãŒãžãšããããŒã«åé¢ããèšèªã§ã¯ãå®å
šãªæå·é¢æ°ãšå®å
šã§ãªãæå·é¢æ°ãåãããã±ãŒãžãšããããŒã«å«ããã¹ãã§ã¯ãããŸããã ãµãã¿ã€ããæã€èšèªã§ã¯ãå®å
šãªæå·åãå®çŸããããã«åå¥ã®ã¿ã€ããå¿
èŠã§ãã
笊å·ãªãã®åã䜿çšããŠããã€ããªããŒã¿ãè¡šããŸãã
åé¡
äžéšã®Cã©ã€ã¯ãªèšèªã§ã¯ã笊å·ä»ãæŽæ°åãšç¬Šå·ãªãæŽæ°åã¯ç°ãªããŸãã ç¹ã«ãCã§ã¯ãåé¡ã¯type | char | iconicã¯å®è£ ã«äŸåããŸãã ããã¯ãããšãã°æ¬¡ã®ãããªåé¡ã®ããã³ãŒãã«ã€ãªããå¯èœæ§ããããŸãã
int decrypt_data(const char *key, char *bytes, size_t len); void fn(...) { //... char *name; char buf[257]; decrypt_data(key, buf, 257); int name_len = buf[0]; name = malloc(name_len + 1); memcpy(name, buf+1, name_len); name[name_len] = 0; //... }
If | char | 笊å·ãªãã®å Žåããã®ã³ãŒãã¯æåŸ ã©ããã«åäœããŸãã ãããããã| char | éèŠã| buf [0] | ã¯è² ã®å€ããšãããšãã§ããé¢æ°ã®åŒæ°ã®å€ãéåžžã«å€§ãããªããŸã| malloc | ããã³| memcpy | æåŸã®æåã®å€ã0ã«èšå®ããããšãããšãããŒããç Žæããå¯èœæ§ããããŸããç¶æ³ã¯ããã«æªåããå¯èœæ§ããããŸã| buf [0] | 255ã®å Žåãname_lenã¯-1ã«ãªããŸãã ãããã£ãŠãã¡ã¢ãªã«ãµã€ãº0ãã€ãã®ãããã¡ãå²ãåœãŠã次ã«ã³ããŒããŸã|ïŒsize_tïŒ-1 memcpy | ããŒããè©°ãŸããããã®ãããã¡ã«ã
解決ç
笊å·ä»ããã€ãåãšç¬Šå·ãªããã€ãåãåºå¥ããèšèªã§ã¯ãå®è£ ã¯ç¬Šå·ãªãåã䜿çšããŠAPIã§ãã€ãæååãè¡šãå¿ èŠããããŸãã
æ©å¯ããŒã¿ã®ã¡ã¢ãªãã¯ãªã¢
åé¡
ã»ãšãã©ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã¯ãæåã®ããã»ã¹ãã·ã¹ãã ã«ã¡ã¢ãªãåæ¢ãŸãã¯è¿ãããããããããã»ã¹ã§äœ¿çšãããã¡ã¢ãªãæåã«ã¯ãªã¢ããã«å¥ã®ããã»ã¹ã§äœ¿çšã§ããŸãã ã¡ã¢ãªã«ç§å¯ããŒãå«ãŸããŠããå Žåããããã¯å¥ã®ããã»ã¹ã§äœ¿çšã§ããããã䟵害ãããå¯èœæ§ãé«ããªããŸãã ãã«ããŠãŒã¶ãŒã·ã¹ãã ã§ã¯ãããã«ãããã·ã¹ãã ã®ä»ã®ãŠãŒã¶ãŒã®ããŒã決å®ã§ããŸãã åãã·ã¹ãã å ã§ãã£ãŠãããã®ãããªç¶æ³ã¯ã以åã¯æ¯èŒçãå®å šãªãè匱æ§ãæ©å¯ããŒã¿ã®æŒæŽ©ã«ã€ãªããå¯èœæ§ããããšããäºå®ã«ã€ãªããå¯èœæ§ããããŸãã
解決ç
æ©å¯ããŒã¿ãå«ããã¹ãŠã®å€æ°ã¯ãå¿ãããŸã§ã¯ãªã¢ãã䜿çšãåæ¢ããŠãã ããã | mmapïŒïŒ|é¢æ°ã䜿çšãã å®è¡äž| munmapïŒïŒ| ããã«ã¡ã¢ãªã解æŸãããã¡ã¢ãªãå¶åŸ¡ã§ããªããªããŸãã
ã¡ã¢ãªãã¯ãªã¢ããããèŠéå€ã®ãªããžã§ã¯ããç Žå£ããã«ã¯ãå¯èœãªå Žåã¯ãã©ãããã©ãŒã ã«äŸåããã¡ã¢ãªã¯ãªãŒãã³ã°æ©èœã䜿çšããŸã-SecureZeroMemoryïŒïŒ|ãªã© win32ãŸãã¯| OPENSSL_cleanseïŒïŒ| opensslã®å Žåã
Cã®å€ããå°ãªããæ®éçãªè§£æ±ºçã¯æ¬¡ã®ãšããã§ãã
void burn( void *v, size_t n ) { volatile unsigned char *p = ( volatile unsigned char * )v; while( n-- ) *p++ = 0; }
匷ãäžèŽã䜿çšãã
åé¡
å€ãã®æå·ã·ã¹ãã ã¯ã©ã³ãã æ§ã®ãœãŒã¹ãå¿ èŠãšãããã®ãããªã·ã¹ãã ã¯ããã®ãããªãœãŒã¹ã®ã©ã³ãã æ§ããã®ããããªéžè±ã®å Žåã§ãå®å šã§ãªããªãå¯èœæ§ããããŸãã ããšãã°ãDSAã§ä¹±æ°ã1ã€ã§ããªãŒã¯ãããšãç§å¯ããŒã®æ±ºå®ãéåžžã«é«éã«ãªããŸãã äžååãªã©ã³ãã æ§ãå€æããã®ã¯éåžžã«å°é£ã§ããOpenSSLã§ã®Debianä¹±æ°ãžã§ãã¬ãŒã¿ãŒã®ãšã©ãŒã¯2幎éæ°ä»ããããå€æ°ã®ããŒã®äŸµå®³ã«ã€ãªãããŸããã æå·åã¢ããªã±ãŒã·ã§ã³ã®ä¹±æ°ã®èŠä»¶ã¯éåžžã«å³å¯ã§ããå€ãã®æ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ãŒã¯ããããæºãããŠããŸããã
æªã決æ
æå·åã¢ããªã±ãŒã·ã§ã³ã®å Žå
- ã¿ã€ã ã¹ã¿ã³ããèå¥åã枩床ã»ã³ãµãŒãªã©ãã©ã³ãã æ§ã®äºæž¬å¯èœãªãœãŒã¹ã«äŸåããªãã§ãã ããã
- | randïŒïŒ|ã| srandïŒïŒ|ã| randomïŒïŒ|ãªã©ã®äžè¬çãªæ¬äŒŒä¹±æ°çæé¢æ°ã«äŸåããªãã§ãã ããã ã©ã€ãã©ãª| stdlib | ãŸãã¯|ã©ã³ãã | Pythonèšèª
- Mersenne Twisterãžã§ãã¬ãŒã¿ãŒã¯äœ¿çšããªãã§ãã ãã
- www.random.orgãªã©ã®ãªãœãŒã¹ã䜿çšããªãã§ãã ããïŒã©ã³ãã ããŒã¿ã¯ç¬¬äžè
ã«ç¥ããããã第äžè
ã«ãã£ãŠäœ¿çšãããå ŽåããããŸãïŒã
- 匷åãªæå·ããªããã£ãã«åºã¥ããŠããå Žåã§ããç¬èªã®ä¹±æ°ãžã§ãã¬ãŒã¿ãŒã䜿çšããªãã§ãã ããïŒæ£ç¢ºã«äœãããŠããã®ãããããªãå ŽåïŒã
- ãçµæžçãªãæ¶è²»ã®ããã«ãã¢ããªã±ãŒã·ã§ã³ã®ç°ãªãå Žæã§åãã©ã³ãã ãããã䜿çšããªãã§ãã ããã
- çºé»æ©ã¯ã ãã€ããŒããŸãã¯NISTãã¹ãã«åæ Œãããšããçç±ã ãã§å®å®ããŠãããšçµè«ä»ããªãã§ãã ããã
- æå·çã«å ç¢ãªãžã§ãã¬ãŒã¿ãŒã¯ãå¿ ãããåæ¹èªã¿åããšåŸæ¹èªã¿åããä¿è·ãããšçµè«ä»ããªãã§ãã ããã
- ã©ã³ãã ããŒã¿ãšããŠçŽç²ãªåœ¢ã§ãã©ã³ãã æ§ãã䜿çšããªãã§ãã ããïŒã¢ããã°ã©ã³ãã ãœãŒã¹ã«ã¯åå·®ãããããšãå€ãããããã®ãããªãœãŒã¹ããåä¿¡ããNãããã¯Nã©ã³ãã ãããæªæºã§ãïŒã
解決ç
ããªããã£ããšãã®èšèšãéžæããããšã«ãããã©ã³ãã æ§ã®äœ¿çšãæå°éã«æããŸãïŒããšãã°ã Ed25519ã䜿çšãããšã決å®çãªæ¹æ³ã§é»å眲åã®æ²ç·ãååŸã§ããŸã ïŒã ä¹±æ°ãçæããã«ã¯ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠæäŸãããæå·åèŠä»¶ãæºããããšãä¿èšŒããããœãŒã¹ïŒ| / dev / random |ãªã©ïŒã䜿çšããŸãã ãªãœãŒã¹ã«å¶éã®ãããã©ãããã©ãŒã ã§ã¯ãã¢ããã°ã©ã³ãã ãã€ãºãœãŒã¹ãšé©åãªæ··ç·Žæé ã®äœ¿çšãæ€èšããŠãã ããã
ã»ã³ãµãŒãçæããå€ããã§ãã¯ããŠãåä¿¡ãããã€ããæ¬æ¥ããã¹ããã®ã§ãããæ£ããæžã蟌ãŸããŠããããšã確èªããŠãã ããã
Nadi Heninger et alãã®èšäºã®ã»ã¯ã·ã§ã³7ã®æšå¥šäºé ã«åŸã£ãŠãã ããã
Ivy Bridgeã¢ãŒããã¯ãã£ïŒããã³ãã以éã®äžä»£ïŒãæèŒããIntelããã»ããµã§ã¯ãçµã¿èŸŒã¿ã®ãžã§ãã¬ãŒã¿ãŒãé«ããšã³ããããŒãšé床ãä¿èšŒããŸãã
Unixã·ã¹ãã ã¯éåžžã次ã䜿çšããŸã| / dev / random | ãŸãã¯| / dev / urandom |ã ãã ãããããã®ãã¡ã®æåã®ãã®ã«ã¯ããããã³ã°ããããã£ããããŸãã ååãªã©ã³ãã æ§ãèç©ãããŠããªããšèããããå Žåãå€ãè¿ããŸããã ãã®ããããã£ã¯ã䜿ãããããå¶éããŸãã
ãã®äœ¿çšããããã£ãŠ| / dev / urandom | ããé »ç¹ã«äœ¿çšãããŸãã 䜿çš| / dev / urandom | ååç°¡åïŒ
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { int randint; int bytes_read; int fd = open("/dev/urandom", O_RDONLY); if (fd != -1) { bytes_read = read(fd, &randint, sizeof(randint)); if (bytes_read != sizeof(randint)) { fprintf(stderr, "read() failed (%d bytes read)\n", bytes_read); return -1; } } else { fprintf(stderr, "open() failed\n"); return -2; } printf("%08x\n", randint); /* assumes sizeof(int) <= 4 */ close(fd); return 0; }
ãã ãããã®åçŽãªããã°ã©ã ã§ã¯ãã©ã³ãã æ§ãå®å šã«çæããã«ã¯äžååãªå ŽåããããŸããé¢æ°| getentropy_urandom |ã®ããã«ãè¿œå ã®ãšã©ãŒãã§ãã¯ãå®è¡ããæ¹ãå®å šã§ãã ãªãã¬ã¹ã«
static int getentropy_urandom(void *buf, size_t len) { struct stat st; size_t i; int fd, cnt, flags; int save_errno = errno; start: flags = O_RDONLY; #ifdef O_NOFOLLOW flags |= O_NOFOLLOW; #endif #ifdef O_CLOEXEC flags |= O_CLOEXEC; #endif fd = open("/dev/urandom", flags, 0); if (fd == -1) { if (errno == EINTR) goto start; goto nodevrandom; } #ifndef O_CLOEXEC fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); #endif /* Lightly verify that the device node looks sane */ if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { close(fd); goto nodevrandom; } if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) { close(fd); goto nodevrandom; } for (i = 0; i < len; ) { size_t wanted = len - i; ssize_t ret = read(fd, (char *)buf + i, wanted); if (ret == -1) { if (errno == EAGAIN || errno == EINTR) continue; close(fd); goto nodevrandom; } i += ret; } close(fd); if (gotdata(buf, len) == 0) { errno = save_errno; return 0; /* satisfied */ } nodevrandom: errno = EIO; return -1; }
Windowsã·ã¹ãã ã®å Žå| CryptGenRandom | Win32 APIã¯ãæå·åã§ã®äœ¿çšã«é©ããæ¬äŒŒã©ã³ãã ããããçæããŸãã ãã€ã¯ããœããã§ã¯ã次ã®ãŠãŒã¹ã±ãŒã¹ãæäŸããŠããŸãã
#include <stddef.h> #include <stdint.h> #include <windows.h> #pragma comment(lib, "advapi32.lib") int randombytes(unsigned char *out, size_t outlen) { static HCRYPTPROV handle = 0; /* only freed when program ends */ if(!handle) { if(!CryptAcquireContext(&handle, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { return -1; } } while(outlen > 0) { const DWORD len = outlen > 1048576UL ? 1048576UL : outlen; if(!CryptGenRandom(handle, len, out)) { return -2; } out += len; outlen -= len; } return 0; }
Windows XP以éã§ã®äœ¿çšã«çŠç¹ãåãããŠããå Žåãäžèšã®CryptoAPIã³ãŒãã¯| RtlGenRandom |
#include <stdint.h> #include <stdio.h> #include <Windows.h> #define RtlGenRandom SystemFunction036 #if defined(__cplusplus) extern "C" #endif BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); #pragma comment(lib, "advapi32.lib") int main() { uint8_t buffer[32] = { 0 }; if (FALSE == RtlGenRandom(buffer, sizeof buffer)) return -1; for (size_t i = 0; i < sizeof buffer; ++i) printf("%02X ", buffer[i]); printf("\n"); return 0; }