node-qrcode показывает другой код, который нельзя изменить на стороне сервера, используя Otp.NET - PullRequest
0 голосов
/ 18 апреля 2020

Я столкнулся с действительно странной проблемой и почти перепробовал все возможные комбинации, которые мне удалось решить. К сожалению, код qr, который сканирует приложение Google Authenticator, не соответствует тому, что вычисляет Otp. NET на стороне сервера.

Я использовал тот же ключ, алгоритм для генерации кода Qr на стороне клиента, который затем сканируется и передается на сторону сервера для изменения, которое не удается. Следующим является исходный код для стороны сервера:

Код стороны обслуживания. (Генерация ключа / секрета) Используемая библиотека: https://github.com/kspearrin/Otp.NET

 var otpSeed = KeyGeneration.GenerateRandomKey(OtpHashMode.Sha512);
 userIdentity.OTPSeed = otpSeed;

 customResponse.Add(TwoFASeedKey, Base32Encoding.ToString(key));
 customResponse.Add("OtpHashMode", "SHA512");
 customResponse.Add("Username", "alice@demo");
 customResponse.Add("Issuer", "demo Issuer");

При использовании следующего кода для изменения кода OtpCode, отправляемого со стороны клиента.

public bool VerifyOtp(byte[] otpSeed, string otpCode) // otpSeed is the same secret which is being generated at the first step.
{
   var totp = new Totp(otpSeed, 30, OtpHashMode.Sha512, 6);
   return totp.VerifyTotp(otpCode, out var timeWindow, VerificationWindow.RfcSpecifiedNetworkDelay)
}

, в то время как ниже приведен код на стороне клиента, который извлекает вышеуказанные данные в качестве обратного вызова.

Clientside

Используется библиотека для генерации метода QRCode: (toDataURL) из https://www.npmjs.com/package/qrcode#createtext -опций

 public void postLogin(){
      await this.oauthService.fetchTokenUsingPasswordFlow(username, password)
            .then(response => {

            const state = response['2FAState'];

       const seed = response['2FASeed'];
       const issuer = response['Issuer'];
       const userName = response['Username'];
       const otpHashMode = response['OtpHashMode'];


       this.username = userName;
       this.totpUri = this.makeTotpUri(seed, issuer, userName, otpHashMode);

       toDataURL(this.totpUri).then((data_url) => {
             this.otpQrCodeUrl = data_url; // This OtpQrCode bound with img src at HTML, which shows QR code png image at screen. Google Auth easily scans that image and shows the 6 digit code.
      });
  });

}

 private toTotpUri({ secret, accountName, issuer, algo, digits, period }:
 {
        secret: string; accountName: string; issuer: string;
        algo: string; digits: number; period: number;
 }) 
 {            
    return `otpauth://totp/${encodeURI(issuer || '')}
            :${encodeURI(accountName || '')}
            ?secret=${secret.replace(/[\s\.\_\-]+/g, '').toUpperCase()}
            &issuer=${encodeURIComponent(issuer || '')}
            &algorithm=${algo}
            &digits=${digits || 6}
            &period=${period || 30}`;
}

public makeTotpUri(seed: string, issuer: string, userName: string, otpHashMode: string): string {

    return this.toTotpUri({ secret: seed, accountName: userName, issuer, 
    algo: otpHashMode, digits: 6, period: 120 });
}

Секрет выборки, сгенерированный из RandomKeyGenerator из Otp. NET

ZYXHYYDP7TJBALMCFZBMLT7ALV3RU53UQ3JAULN7VGFVWEVDR4DLLHJAL7CFMZ4WDIDDWSMZ7O5D73L7KFIR6V3BYNTYJDCIG4KILRQ=

Примечание. Я попытался сгенерировать 6 di git Otp-код вручную на стороне сервера с помощью ComputeHash и изменил его с помощью Otp.Varify, он работал там. Но когда код сканируется из Google Auth, переданный код никогда не совпадает. Я понятия не имею, почему неправильный код генерируется методом QRCode.toDataURL. Любая помощь будет очень признательна, так как я застрял здесь.

...