|
8 | 8 | using System.Threading.Tasks; |
9 | 9 | using Avalonia.Controls; |
10 | 10 | using Microsoft.Extensions.Logging; |
| 11 | +using SecRandom.Core; |
11 | 12 | using SecRandom.Core.Enums.Configs; |
12 | 13 | using SecRandom.Core.Models.SubConfigs; |
13 | 14 | using SecRandom.Core.Services.Config; |
@@ -288,12 +289,15 @@ public Task<SecurityVerificationResult> VerifyAsync( |
288 | 289 | var usbPassed = factors.Contains(SecurityFactor.Usb) && |
289 | 290 | response.UsbPresent && |
290 | 291 | metadata.UsbBindings.Any(IsBindingPresent); |
291 | | - // 「任意已选验证方式」模式下 TOTP 也能单独通过:该模式会用凭据文件旁的 |
292 | | - // 免密副本校验验证码,因此不需要先解开信封 |
293 | | - var totpPassed = GlobalConstants.AllowStandaloneTotpVerification && |
294 | | - factors.Contains(SecurityFactor.Totp) && |
295 | | - credentialStore.LoadStandaloneTotp() is { } standaloneTotp && |
296 | | - TotpService.Verify(standaloneTotp, response.TotpCode, _timeProvider.GetUtcNow()); |
| 292 | + // 「任意已选验证方式」模式下 TOTP 能单独通过,靠的是凭据文件旁的免密副本;本分支默认 |
| 293 | + // 不保留那份可读种子,因此该路径在未显式允许时整体不可用 |
| 294 | + var totpPassed = false; |
| 295 | + if (GlobalConstants.AllowStandaloneTotpVerification |
| 296 | + && factors.Contains(SecurityFactor.Totp) |
| 297 | + && credentialStore.LoadStandaloneTotp() is { } standaloneTotp) |
| 298 | + { |
| 299 | + totpPassed = TotpService.Verify(standaloneTotp, response.TotpCode, _timeProvider.GetUtcNow()); |
| 300 | + } |
297 | 301 | if (!Settings.RequireAllSelectedFactors && (usbPassed || totpPassed)) |
298 | 302 | { |
299 | 303 | metadata.FailedAttempts = 0; |
@@ -880,15 +884,17 @@ private bool TrySaveCredentials(SecurityCredentialContext context) |
880 | 884 | return false; |
881 | 885 | } |
882 | 886 |
|
883 | | - // 信封先落盘,再同步免密 TOTP 副本,避免出现「新种子 / 旧信封」的错配 |
| 887 | + // 信封先落盘,再同步免密 TOTP 副本,避免出现「新种子 / 旧信封」的错配。 |
| 888 | + // 未允许「仅 TOTP」验证时一律删除副本:升级后遗留的明文种子会在下一次保存时被清掉 |
| 889 | + var totpSecret = context.Credentials.TotpSecret; |
884 | 890 | try |
885 | 891 | { |
886 | 892 | if (!GlobalConstants.AllowStandaloneTotpVerification |
887 | 893 | || Settings.RequireAllSelectedFactors |
888 | | - || string.IsNullOrWhiteSpace(context.Credentials.TotpSecret)) |
| 894 | + || string.IsNullOrWhiteSpace(totpSecret)) |
889 | 895 | credentialStore.DeleteStandaloneTotp(); |
890 | 896 | else |
891 | | - credentialStore.SaveStandaloneTotp(context.Credentials.TotpSecret); |
| 897 | + credentialStore.SaveStandaloneTotp(totpSecret); |
892 | 898 | return true; |
893 | 899 | } |
894 | 900 | catch (CryptographicException exception) |
|
0 commit comments