String StringUtil::MD5(const String& input, bool raw /* = false */) { Md5Digest md5(input.data(), input.size()); auto const rawLen = sizeof(md5.digest); if (raw) return String((char*)md5.digest, rawLen, CopyString); auto const hexLen = rawLen * 2; String hex(hexLen, ReserveString); string_bin2hex((char*)md5.digest, rawLen, hex.bufferSlice().ptr); return hex.setSize(hexLen); }
String StringUtil::MD5(const char *data, uint32_t size, bool raw /* = false */) { Md5Digest md5(data, size); auto const rawLen = sizeof(md5.digest); if (raw) return String((char*)md5.digest, rawLen, CopyString); auto const hexLen = rawLen * 2; String hex(hexLen, ReserveString); string_bin2hex((char*)md5.digest, rawLen, hex.mutableData()); hex.setSize(hexLen); return hex; }
/** メッセージを暗号化する * @param[in] peer_addr 送信先IPアドレス * @param[in] message 暗号化するメッセージ * @param[out] ret_str 暗号化したメッセージを指すポインタ変数のアドレス * @param[out] len 暗号化メッセージ長返却領域 * @retval 0 正常終了 * @retval -EINVAL 引数異常 */ int ipmsg_encrypt_message(const char *peer_addr, const char *message, unsigned char **ret_str, size_t *len) { int rc = 0; int retry = 0; unsigned long peer_cap = 0; unsigned long skey_type = 0, akey_type = 0; char *session_key = NULL; char *enc_skey = NULL; size_t skey_len = 0; char *key_e = NULL, *key_n = NULL; char *raw_enc_body = NULL; unsigned char *enc_body = NULL; size_t enc_len = 0; unsigned char *encrypted_message = NULL; size_t total_len = 0; unsigned char *sign = NULL; unsigned long sign_type = 0; int i = 0; if ( (peer_addr == NULL) || (message == NULL) || (ret_str == NULL) || (len == NULL) ) { rc = -EINVAL; goto error_out; } /* 相手の暗号化能力を取得 */ retry = PUBKEY_MAX_RETRY; do{ rc = userdb_wait_public_key(peer_addr, &peer_cap, &key_e, &key_n); if ( (rc < 0) && (rc != -EINTR) ) { goto error_out; /* 明示的なエラー */ } if (rc == 0) { /* 見付けた */ dbg_out("Found: \n\taddr = %s\n" "\tcap = %x\n" "\tpubkey-e = %s\n" "\tpubkey-n = %s\n", peer_addr, peer_cap, key_e, key_n); break; } --retry; } while(retry > 0); if ( (rc != 0) && (retry == 0) ) goto free_peer_key_out; /* 取得失敗 */ /* *暗号化アルゴリズムを選択 */ rc = select_symmetric_key(peer_cap, &skey_type, hostinfo_refer_ipmsg_crypt_policy_is_speed()); if (rc != 0) goto free_peer_key_out; /* * セッションキー作成と本文の暗号化 */ rc = symcrypt_encrypt_message(skey_type, message, &session_key, &skey_len, &raw_enc_body, &enc_len); if (rc != 0) goto free_peer_key_out; rc = string_bin2hex((const u_int8_t *)raw_enc_body, enc_len, &enc_body); if (rc != 0) goto free_session_key_out; /* * セッションキーを暗号化 */ rc = pcrypt_encrypt_message(peer_cap, key_e, key_n, session_key, skey_len, &enc_skey, &akey_type); if (rc != 0) goto free_enc_body_out; /* * 暗号化文字列長取得 * longの長さは, 64ビット環境の場合は, 8バイトになるので, * 1バイトあたりの表示領域長(2)をlongのバイト長文だけ掛け合わせることで, * 領域長に対するアーキ依存性を排除する. * +3はデリミタ(':')2つとヌルターミネートの分 */ total_len = sizeof(unsigned long) * 2 + strlen(enc_skey) + strlen(enc_body) + 3; encrypted_message = g_malloc(total_len); if (encrypted_message == NULL) { rc = -ENOMEM; goto free_encoded_session_key; } /* *署名を選択する */ rc = select_signature(peer_cap, &sign_type, hostinfo_refer_ipmsg_crypt_policy_is_speed()); if (rc != 0) { sign_type = 0; /* 署名を使用しない */ } snprintf(encrypted_message, total_len, "%x:%s:%s", (skey_type|akey_type|sign_type), enc_skey, enc_body); dbg_out("Encrypted body:%s\n", encrypted_message); if (sign_type != 0) { /* * 小文字に変換 */ for(i = 0; i < total_len; ++i) { encrypted_message[i] = tolower((int)encrypted_message[i]); } rc = pcrypt_sign(akey_type, sign_type, encrypted_message, &sign); if (rc != 0) goto free_sign_out; g_free(encrypted_message); /* * 署名を付して本文を再作成 */ total_len += (strlen(sign) + 1); /* +1は, デリミタ分 */ encrypted_message = g_malloc(total_len); if (encrypted_message == NULL) goto free_sign_out; snprintf(encrypted_message, total_len, "%x:%s:%s:%s", (skey_type|akey_type|sign_type), enc_skey, enc_body, sign); dbg_out("Signed body:%s\n", encrypted_message); } /* * 小文字に変換 */ total_len = strlen(encrypted_message); for(i = 0; i < total_len; ++i) { encrypted_message[i] = tolower((int)encrypted_message[i]); } /* * 解析結果返却 */ *ret_str = encrypted_message; *len = total_len; rc = 0; free_sign_out: if (sign != NULL) g_free(sign); free_enc_body_out: if (enc_body != NULL) g_free(enc_body); free_encoded_session_key: if (enc_skey != NULL) g_free(enc_skey); free_session_key_out: if (session_key != NULL) g_free(session_key); if (raw_enc_body != NULL) g_free(raw_enc_body); free_peer_key_out: if (key_e != NULL) g_free(key_e); if (key_n != NULL) g_free(key_n); error_out: return rc; }
String StringUtil::HexEncode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_bin2hex(input.data(), len); return String(ret, len, AttachString); }