UE4中实现PBKDF2加密验证

UE4中Crypto++库加密解密

第三节:UE4中实现PBKDF2加密验证



前言

通过哈希算法进行加密。因为哈希算法是单向的,可以将任何大小的数据转化为定长的“指纹”,而且无法被反向计算。另外,即使数据源只改动了一丁点,哈希的结果也会完全不同。这样的特性使得它非常适合用于保存密码,因为我们需要加密后的密码无法被解密,同时也能保证正确校验每个用户的密码。但是哈希加密可以通过字典攻击和暴力攻击破解。
密码加盐。盐是一个添加到用户的密码哈希过程中的一段随机序列。这个机制能够防止通过预先计算结果的彩虹表破解。每个用户都有自己的盐,这样的结果就是即使用户的密码相同,通过加盐后哈希值也将不同。为了校验密码是否正确,我们需要储存盐值。通常和密码哈希值一起存放在账户数据库中,或者直接存为哈希字符串的一部分。


提示:以下是本篇文章正文内容,下面案例可供参考

代码

首先要生成一个盐值salt,再把原始密码和salt加密得到密文。验证的时候,把用户输入的密码和同样的盐值salt使用相同的加密算法得到一个密文,将这个密文和原密文相比较,相同则验证通过,反之则不通过。
以下为实现逻辑:

1. C++代码

MyPBKDF2.h

#pragma once

#include "CoreMinimal.h"

#include "../ThirdParty/crypto/include/Win64/config_int.h"
#include "../ThirdParty/crypto/include/Win64/pwdbased.h"
#include "../ThirdParty/crypto/include/Win64/sha.h"
#include "../ThirdParty/crypto/include/Win64/hex.h"
#include "../ThirdParty/crypto/include/Win64/cryptlib.h"
#include "../ThirdParty/crypto/include/Win64/blake2.h"
#include "../ThirdParty/crypto/include/Win64/files.h"
#include "../ThirdParty/crypto/include/Win64/aes.h"
#include "../ThirdParty/crypto/include/Win64/modes.h"
#include "../ThirdParty/crypto/include/Win64/pubkey.h"
using namespace CryptoPP;

#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyPBKDF2.generated.h"

/**
 * 
 */
UCLASS()
class TEST_API UMyPBKDF2 : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	//PBKDF2算法
	//验证密码
	UFUNCTION(BlueprintCallable, meta = (DisplayName = "authenticate", Keywords = "authenticate", pbkdf2_key = "0123456789ABCDEF0123456789ABCDEF"), Category = "PBKDF2")
    static bool authenticate(FString attemptedPassword, FString encryptedPassword, FString pbkdf2_key);

	//生成密文
	UFUNCTION(BlueprintCallable, meta = (DisplayName = "getEncryptedPassword", Keywords = "getEncryptedPassword", pbkdf2_key = "0123456789ABCDEF0123456789ABCDEF"), Category= "PBKDF2")
	static  FString getEncryptedPassword(FString pbkdf2_content, FString pbkdf2_key);

};

MyPBKDF2.cpp

include "MyPBKDF2.h"
/**
* 对输入的password进行验证
* 
* @param attemptedPassword
*            待验证的password
* @param encryptedPassword
*            密文
* @param salt
*            盐值
* @return 是否验证成功
*/
#pragma region PBKDF2
bool UMyPBKDF2::authenticate(FString attemptedPassword, FString encryptedPassword, FString salt)
{
	// 用同样的盐值对用户输入的password进行加密
	FString encryptedAttemptedPassword = getEncryptedPassword(attemptedPassword, salt);
	// 把加密后的密文和原密文进行比較,同样则验证成功。否则失败
	return encryptedAttemptedPassword.Equals(encryptedPassword);
}

/**
* 生成密文
* 
* @param password
*            明文password
* @param salt
*            盐值
* @return
*/
FString UMyPBKDF2::getEncryptedPassword(FString pbkdf2_content, FString pbkdf2_key)
{
	std::string _pbkdf2_content = TCHAR_TO_UTF8(*pbkdf2_content);
	byte password[AES::MAX_KEYLENGTH];
	size_t plen = _pbkdf2_content.size();
	plen <= AES::MAX_KEYLENGTH ? memcpy(password, _pbkdf2_content.c_str(), plen) : memcpy(password, _pbkdf2_content.c_str(), AES::MAX_KEYLENGTH);

	std::string _pbkdf2_key = TCHAR_TO_UTF8(*pbkdf2_key);
	byte salt[AES::MAX_KEYLENGTH];
	size_t slen = _pbkdf2_key.size();
	slen <= AES::MAX_KEYLENGTH ? memcpy(salt, _pbkdf2_key.c_str(), slen) : memcpy(salt, _pbkdf2_key.c_str(), AES::MAX_KEYLENGTH);

	byte derived[SHA256::DIGESTSIZE];

	PKCS5_PBKDF2_HMAC<SHA256> pbkdf;
	byte unused = 0;

	pbkdf.DeriveKey(derived, sizeof(derived), unused, password, plen, salt, slen, 1024, 0.0f);

	std::string result;
	HexEncoder encoder(new StringSink(result));

	encoder.Put(derived, sizeof(derived));
	encoder.MessageEnd();

	return UTF8_TO_TCHAR(result.c_str());
}
#pragma endregion

2. 蓝图

在这里插入图片描述

测试结果

行效果如下:
在这里插入图片描述
完美实现加密验证。


参考

PBKDF2加密的实现
安全密码存储,该怎么做,不该怎么做?
Node.js crypto.pbkdf2()用法及代码示例
如何使用 PKCS5_PBKDF2_HMAC_SHA1()
PKCS5 PBKDF2 HMAC官方文档
crypto加密解密

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值