├── .gitignore ├── LICENSE ├── README.md ├── TOTP.sln ├── TOTP ├── Base32.cs ├── Properties │ └── AssemblyInfo.cs ├── TOTPLib.csproj └── Totp.cs ├── TOTPGui ├── App.config ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── TOTPGui.cs └── TOTPGui.csproj └── TOTPTests ├── Properties └── AssemblyInfo.cs ├── TOTPTests.csproj └── TotpTests.cs /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | [Rr]eleases/ 14 | x64/ 15 | x86/ 16 | build/ 17 | bld/ 18 | [Bb]in/ 19 | [Oo]bj/ 20 | 21 | # Roslyn cache directories 22 | *.ide/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | #NUNIT 29 | *.VisualState.xml 30 | TestResult.xml 31 | 32 | # Build Results of an ATL Project 33 | [Dd]ebugPS/ 34 | [Rr]eleasePS/ 35 | dlldata.c 36 | 37 | *_i.c 38 | *_p.c 39 | *_i.h 40 | *.ilk 41 | *.meta 42 | *.obj 43 | *.pch 44 | *.pdb 45 | *.pgc 46 | *.pgd 47 | *.rsp 48 | *.sbr 49 | *.tlb 50 | *.tli 51 | *.tlh 52 | *.tmp 53 | *.tmp_proj 54 | *.log 55 | *.vspscc 56 | *.vssscc 57 | .builds 58 | *.pidb 59 | *.svclog 60 | *.scc 61 | 62 | # Chutzpah Test files 63 | _Chutzpah* 64 | 65 | # Visual C++ cache files 66 | ipch/ 67 | *.aps 68 | *.ncb 69 | *.opensdf 70 | *.sdf 71 | *.cachefile 72 | 73 | # Visual Studio profiler 74 | *.psess 75 | *.vsp 76 | *.vspx 77 | 78 | # TFS 2012 Local Workspace 79 | $tf/ 80 | 81 | # Guidance Automation Toolkit 82 | *.gpState 83 | 84 | # ReSharper is a .NET coding add-in 85 | _ReSharper*/ 86 | *.[Rr]e[Ss]harper 87 | *.DotSettings.user 88 | 89 | # JustCode is a .NET coding addin-in 90 | .JustCode 91 | 92 | # TeamCity is a build add-in 93 | _TeamCity* 94 | 95 | # DotCover is a Code Coverage Tool 96 | *.dotCover 97 | 98 | # NCrunch 99 | _NCrunch_* 100 | .*crunch*.local.xml 101 | 102 | # MightyMoose 103 | *.mm.* 104 | AutoTest.Net/ 105 | 106 | # Web workbench (sass) 107 | .sass-cache/ 108 | 109 | # Installshield output folder 110 | [Ee]xpress/ 111 | 112 | # DocProject is a documentation generator add-in 113 | DocProject/buildhelp/ 114 | DocProject/Help/*.HxT 115 | DocProject/Help/*.HxC 116 | DocProject/Help/*.hhc 117 | DocProject/Help/*.hhk 118 | DocProject/Help/*.hhp 119 | DocProject/Help/Html2 120 | DocProject/Help/html 121 | 122 | # Click-Once directory 123 | publish/ 124 | 125 | # Publish Web Output 126 | *.[Pp]ublish.xml 127 | *.azurePubxml 128 | # TODO: Comment the next line if you want to checkin your web deploy settings 129 | # but database connection strings (with potential passwords) will be unencrypted 130 | *.pubxml 131 | *.publishproj 132 | 133 | # NuGet Packages 134 | *.nupkg 135 | # The packages folder can be ignored because of Package Restore 136 | **/packages/* 137 | # except build/, which is used as an MSBuild target. 138 | !**/packages/build/ 139 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 140 | #!**/packages/repositories.config 141 | 142 | # Windows Azure Build Output 143 | csx/ 144 | *.build.csdef 145 | 146 | # Windows Store app package directory 147 | AppPackages/ 148 | 149 | # Others 150 | sql/ 151 | *.Cache 152 | ClientBin/ 153 | [Ss]tyle[Cc]op.* 154 | ~$* 155 | *~ 156 | *.dbmdl 157 | *.dbproj.schemaview 158 | *.pfx 159 | *.publishsettings 160 | node_modules/ 161 | 162 | # RIA/Silverlight projects 163 | Generated_Code/ 164 | 165 | # Backup & report files from converting an old project file 166 | # to a newer Visual Studio version. Backup files are not needed, 167 | # because we have git ;-) 168 | _UpgradeReport_Files/ 169 | Backup*/ 170 | UpgradeLog*.XML 171 | UpgradeLog*.htm 172 | 173 | # SQL Server files 174 | *.mdf 175 | *.ldf 176 | 177 | # Business Intelligence projects 178 | *.rdl.data 179 | *.bim.layout 180 | *.bim_*.settings 181 | 182 | # Microsoft Fakes 183 | <<<<<<< HEAD 184 | FakesAssemblies/ 185 | ======= 186 | FakesAssemblies/ 187 | >>>>>>> 41d727aabff0615efe3f566c52804f94caf54d31 188 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # totp-net 2 | a little totp c# library + GUI with google authenticator conform QR-Code generation. 3 | 4 | ## Quickstart 5 | 6 | Generate the Actual code for the Secret GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ. The secret has to be base32 encoded. 7 | In this Example t1 is set to 30sec and we will get a 8 digit long code. 8 | 9 | ```c# 10 | string secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; 11 | Totp totp = new Totp(secret,30,8); 12 | string totpCode = totp.getCodeString(); 13 | ``` 14 | 15 | 16 | ## Resorces 17 | * [rfc6238](https://tools.ietf.org/html/rfc6238) 18 | 19 | ## Used Librarys and Classes 20 | 21 | * [QrCode.Net](http://qrcodenet.codeplex.com/) 22 | * [Circular Progress Bar](https://visualstudiogallery.msdn.microsoft.com/9d2fe9ac-dea4-4551-a015-6c59500c7779) 23 | * [Base32](http://scottless.com/blog/archive/2014/02/15/base32-encoder-and-decoder-in-c.aspx) 24 | -------------------------------------------------------------------------------- /TOTP.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TOTPLib", "TOTP\TOTPLib.csproj", "{2C51FAE6-7F0F-43CC-9EEC-D66958BF99B2}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TOTPTests", "TOTPTests\TOTPTests.csproj", "{DF2DF9D8-9546-4126-AB8B-D6654FA0075F}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TOTPGui", "TOTPGui\TOTPGui.csproj", "{047D1B1F-F3D5-4BE9-91D0-F86F8855B41E}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {2C51FAE6-7F0F-43CC-9EEC-D66958BF99B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {2C51FAE6-7F0F-43CC-9EEC-D66958BF99B2}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {2C51FAE6-7F0F-43CC-9EEC-D66958BF99B2}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {2C51FAE6-7F0F-43CC-9EEC-D66958BF99B2}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {DF2DF9D8-9546-4126-AB8B-D6654FA0075F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {DF2DF9D8-9546-4126-AB8B-D6654FA0075F}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {DF2DF9D8-9546-4126-AB8B-D6654FA0075F}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {DF2DF9D8-9546-4126-AB8B-D6654FA0075F}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {047D1B1F-F3D5-4BE9-91D0-F86F8855B41E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {047D1B1F-F3D5-4BE9-91D0-F86F8855B41E}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {047D1B1F-F3D5-4BE9-91D0-F86F8855B41E}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {047D1B1F-F3D5-4BE9-91D0-F86F8855B41E}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /TOTP/Base32.cs: -------------------------------------------------------------------------------- 1 | //******************************************************************************************************** 2 | // Base32 class 3 | // CC by Oleg Igna - http://scottless.com/blog/archive/2014/02/15/base32-encoder-and-decoder-in-c.aspx 4 | // See the LICENSE under: http://creativecommons.org/licenses/by/2.0/ 5 | //******************************************************************************************************** 6 | 7 | using System; 8 | using System.Runtime.CompilerServices; 9 | using System.Text; 10 | 11 | [assembly: InternalsVisibleTo("Totp")] 12 | 13 | namespace TOTP 14 | { 15 | internal sealed class Base32 16 | { 17 | /// 18 | /// Size of the regular byte in bits 19 | /// 20 | private const int InByteSize = 8; 21 | 22 | /// 23 | /// Size of converted byte in bits 24 | /// 25 | private const int OutByteSize = 5; 26 | 27 | /// 28 | /// Alphabet 29 | /// 30 | private const string Base32Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 31 | 32 | /// 33 | /// Convert byte array to Base32 format 34 | /// 35 | /// An array of bytes to convert to Base32 format 36 | /// Returns a string representing byte array 37 | internal static string ToBase32String(byte[] bytes) 38 | { 39 | // Check if byte array is null 40 | if (bytes == null) 41 | { 42 | return null; 43 | } 44 | // Check if empty 45 | if (bytes.Length == 0) 46 | { 47 | return string.Empty; 48 | } 49 | 50 | // Prepare container for the final value 51 | var builder = new StringBuilder(bytes.Length*InByteSize/OutByteSize); 52 | 53 | // Position in the input buffer 54 | var bytesPosition = 0; 55 | 56 | // Offset inside a single byte that points to (from left to right) 57 | // 0 - highest bit, 7 - lowest bit 58 | var bytesSubPosition = 0; 59 | 60 | // Byte to look up in the dictionary 61 | byte outputBase32Byte = 0; 62 | 63 | // The number of bits filled in the current output byte 64 | var outputBase32BytePosition = 0; 65 | 66 | // Iterate through input buffer until we reach past the end of it 67 | while (bytesPosition < bytes.Length) 68 | { 69 | // Calculate the number of bits we can extract out of current input byte to fill missing bits in the output byte 70 | var bitsAvailableInByte = Math.Min(InByteSize - bytesSubPosition, OutByteSize - outputBase32BytePosition); 71 | 72 | // Make space in the output byte 73 | outputBase32Byte <<= bitsAvailableInByte; 74 | 75 | // Extract the part of the input byte and move it to the output byte 76 | outputBase32Byte |= 77 | (byte) (bytes[bytesPosition] >> (InByteSize - (bytesSubPosition + bitsAvailableInByte))); 78 | 79 | // Update current sub-byte position 80 | bytesSubPosition += bitsAvailableInByte; 81 | 82 | // Check overflow 83 | if (bytesSubPosition >= InByteSize) 84 | { 85 | // Move to the next byte 86 | bytesPosition++; 87 | bytesSubPosition = 0; 88 | } 89 | 90 | // Update current base32 byte completion 91 | outputBase32BytePosition += bitsAvailableInByte; 92 | 93 | // Check overflow or end of input array 94 | if (outputBase32BytePosition >= OutByteSize) 95 | { 96 | // Drop the overflow bits 97 | outputBase32Byte &= 0x1F; // 0x1F = 00011111 in binary 98 | 99 | // Add current Base32 byte and convert it to character 100 | builder.Append(Base32Alphabet[outputBase32Byte]); 101 | 102 | // Move to the next byte 103 | outputBase32BytePosition = 0; 104 | } 105 | } 106 | 107 | // Check if we have a remainder 108 | if (outputBase32BytePosition > 0) 109 | { 110 | // Move to the right bits 111 | outputBase32Byte <<= (OutByteSize - outputBase32BytePosition); 112 | 113 | // Drop the overflow bits 114 | outputBase32Byte &= 0x1F; // 0x1F = 00011111 in binary 115 | 116 | // Add current Base32 byte and convert it to character 117 | builder.Append(Base32Alphabet[outputBase32Byte]); 118 | } 119 | 120 | return builder.ToString(); 121 | } 122 | 123 | /// 124 | /// Convert base32 string to array of bytes 125 | /// 126 | /// Base32 string to convert 127 | /// Returns a byte array converted from the string 128 | internal static byte[] FromBase32String(string base32String) 129 | { 130 | // Check if string is null 131 | if (base32String == null) 132 | { 133 | return null; 134 | } 135 | // Check if empty 136 | if (base32String == string.Empty) 137 | { 138 | return new byte[0]; 139 | } 140 | 141 | // Convert to upper-case 142 | var base32StringUpperCase = base32String.ToUpperInvariant(); 143 | 144 | // Prepare output byte array 145 | var outputBytes = new byte[base32StringUpperCase.Length*OutByteSize/InByteSize]; 146 | 147 | // Check the size 148 | if (outputBytes.Length == 0) 149 | { 150 | throw new ArgumentException( 151 | "Specified string is not valid Base32 format because it doesn't have enough data to construct a complete byte array"); 152 | } 153 | 154 | // Position in the string 155 | var base32Position = 0; 156 | 157 | // Offset inside the character in the string 158 | var base32SubPosition = 0; 159 | 160 | // Position within outputBytes array 161 | var outputBytePosition = 0; 162 | 163 | // The number of bits filled in the current output byte 164 | var outputByteSubPosition = 0; 165 | 166 | // Normally we would iterate on the input array but in this case we actually iterate on the output array 167 | // We do it because output array doesn't have overflow bits, while input does and it will cause output array overflow if we don't stop in time 168 | while (outputBytePosition < outputBytes.Length) 169 | { 170 | // Look up current character in the dictionary to convert it to byte 171 | var currentBase32Byte = Base32Alphabet.IndexOf(base32StringUpperCase[base32Position]); 172 | 173 | // Check if found 174 | if (currentBase32Byte < 0) 175 | { 176 | throw new ArgumentException( 177 | string.Format( 178 | "Specified string is not valid Base32 format because character \"{0}\" does not exist in Base32 alphabet", 179 | base32String[base32Position])); 180 | } 181 | 182 | // Calculate the number of bits we can extract out of current input character to fill missing bits in the output byte 183 | var bitsAvailableInByte = Math.Min(OutByteSize - base32SubPosition, InByteSize - outputByteSubPosition); 184 | 185 | // Make space in the output byte 186 | outputBytes[outputBytePosition] <<= bitsAvailableInByte; 187 | 188 | // Extract the part of the input character and move it to the output byte 189 | outputBytes[outputBytePosition] |= 190 | (byte) (currentBase32Byte >> (OutByteSize - (base32SubPosition + bitsAvailableInByte))); 191 | 192 | // Update current sub-byte position 193 | outputByteSubPosition += bitsAvailableInByte; 194 | 195 | // Check overflow 196 | if (outputByteSubPosition >= InByteSize) 197 | { 198 | // Move to the next byte 199 | outputBytePosition++; 200 | outputByteSubPosition = 0; 201 | } 202 | 203 | // Update current base32 byte completion 204 | base32SubPosition += bitsAvailableInByte; 205 | 206 | // Check overflow or end of input array 207 | if (base32SubPosition >= OutByteSize) 208 | { 209 | // Move to the next character 210 | base32Position++; 211 | base32SubPosition = 0; 212 | } 213 | } 214 | 215 | return outputBytes; 216 | } 217 | } 218 | } -------------------------------------------------------------------------------- /TOTP/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("TOTP")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TOTP")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("1d661e34-326a-48e9-afef-9bdd22fa1595")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /TOTP/TOTPLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2C51FAE6-7F0F-43CC-9EEC-D66958BF99B2} 8 | Library 9 | Properties 10 | TOTP 11 | TOTP 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | -------------------------------------------------------------------------------- /TOTP/Totp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Security.Cryptography; 4 | 5 | [assembly: InternalsVisibleTo("TotpTests")] 6 | 7 | namespace TOTP 8 | { 9 | public class Totp 10 | { 11 | private readonly int digits = 6; 12 | private readonly HMACSHA1 hmac; 13 | private readonly Int32 t1 = 30; 14 | internal byte[] key; 15 | 16 | public Totp(string base32string) 17 | { 18 | key = FromBase32String(base32string); 19 | hmac = new HMACSHA1(key); 20 | } 21 | 22 | public Totp(string base32string, Int32 t1, int digits) : this(base32string) 23 | { 24 | this.t1 = t1; 25 | this.digits = digits; 26 | } 27 | 28 | private byte[] FromBase32String(string base32string) 29 | { 30 | return Base32.FromBase32String(base32string); 31 | } 32 | 33 | public static string ToBase32String(byte[] data) 34 | { 35 | return Base32.ToBase32String(data); 36 | } 37 | 38 | public int getCode() 39 | { 40 | var unixTimestamp = (UInt64) (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 41 | 42 | return getCode(unixTimestamp); 43 | } 44 | 45 | public int getCode(UInt64 timeStamp) 46 | { 47 | var message = timeStamp/(UInt64) t1; 48 | var msg_byte = BitConverter.GetBytes(message); 49 | if (BitConverter.IsLittleEndian) 50 | Array.Reverse(msg_byte, 0, msg_byte.Length); 51 | var hash = hmac.ComputeHash(msg_byte); 52 | var offset = (hash[hash.Length - 1] & 0xf); 53 | var i = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | 54 | (hash[offset + 3] & 0xff); 55 | var code = i%(int) Math.Pow(10, digits); 56 | return code; 57 | } 58 | 59 | public String getCodeString() 60 | { 61 | var unixTimestamp = (UInt64) (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 62 | 63 | return getCodeString(unixTimestamp); 64 | } 65 | 66 | public String getCodeString(UInt64 timeStamp) 67 | { 68 | var ret = getCode(timeStamp) + ""; 69 | return ret.PadLeft(digits, '0'); 70 | } 71 | 72 | public static bool CheckBase32(string base32string) 73 | { 74 | try 75 | { 76 | var tmp = Base32.FromBase32String(base32string); 77 | return tmp != null; 78 | } 79 | catch 80 | { 81 | return false; 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /TOTPGui/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /TOTPGui/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TOTPGui 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 33 | this.label2 = new System.Windows.Forms.Label(); 34 | this.textBoxSecret = new System.Windows.Forms.TextBox(); 35 | this.label3 = new System.Windows.Forms.Label(); 36 | this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); 37 | this.textBoxCodeOutput = new System.Windows.Forms.TextBox(); 38 | this.circularProgressBar = new ProgressBar.CircularProgressBar(); 39 | this.buttonGenerate = new System.Windows.Forms.Button(); 40 | this.timer1 = new System.Windows.Forms.Timer(this.components); 41 | this.label4 = new System.Windows.Forms.Label(); 42 | this.numericUpDown2 = new System.Windows.Forms.NumericUpDown(); 43 | this.qrCodeImgControl = new Gma.QrCodeNet.Encoding.Windows.Forms.QrCodeImgControl(); 44 | this.textBoxUser = new System.Windows.Forms.TextBox(); 45 | this.textBoxLable = new System.Windows.Forms.TextBox(); 46 | this.label5 = new System.Windows.Forms.Label(); 47 | this.label6 = new System.Windows.Forms.Label(); 48 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 49 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 50 | this.groupBox2 = new System.Windows.Forms.GroupBox(); 51 | ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit(); 52 | ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit(); 53 | ((System.ComponentModel.ISupportInitialize)(this.qrCodeImgControl)).BeginInit(); 54 | this.groupBox1.SuspendLayout(); 55 | this.groupBox2.SuspendLayout(); 56 | this.SuspendLayout(); 57 | // 58 | // label2 59 | // 60 | this.label2.AutoSize = true; 61 | this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 62 | this.label2.Location = new System.Drawing.Point(9, 19); 63 | this.label2.Name = "label2"; 64 | this.label2.Size = new System.Drawing.Size(47, 16); 65 | this.label2.TabIndex = 0; 66 | this.label2.Text = "Secret"; 67 | // 68 | // textBoxSecret 69 | // 70 | this.textBoxSecret.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 71 | | System.Windows.Forms.AnchorStyles.Right))); 72 | this.textBoxSecret.Location = new System.Drawing.Point(58, 16); 73 | this.textBoxSecret.Name = "textBoxSecret"; 74 | this.textBoxSecret.Size = new System.Drawing.Size(648, 20); 75 | this.textBoxSecret.TabIndex = 1; 76 | // 77 | // label3 78 | // 79 | this.label3.AutoSize = true; 80 | this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 81 | this.label3.Location = new System.Drawing.Point(9, 49); 82 | this.label3.Name = "label3"; 83 | this.label3.Size = new System.Drawing.Size(42, 16); 84 | this.label3.TabIndex = 2; 85 | this.label3.Text = "Digits"; 86 | // 87 | // numericUpDown1 88 | // 89 | this.numericUpDown1.Location = new System.Drawing.Point(58, 45); 90 | this.numericUpDown1.Maximum = new decimal(new int[] { 91 | 8, 92 | 0, 93 | 0, 94 | 0}); 95 | this.numericUpDown1.Name = "numericUpDown1"; 96 | this.numericUpDown1.Size = new System.Drawing.Size(120, 20); 97 | this.numericUpDown1.TabIndex = 3; 98 | this.numericUpDown1.Value = new decimal(new int[] { 99 | 6, 100 | 0, 101 | 0, 102 | 0}); 103 | // 104 | // textBoxCodeOutput 105 | // 106 | this.textBoxCodeOutput.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 107 | this.textBoxCodeOutput.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(192)))), ((int)(((byte)(255))))); 108 | this.textBoxCodeOutput.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 109 | this.textBoxCodeOutput.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 110 | this.textBoxCodeOutput.ForeColor = System.Drawing.Color.Black; 111 | this.textBoxCodeOutput.Location = new System.Drawing.Point(6, 116); 112 | this.textBoxCodeOutput.Name = "textBoxCodeOutput"; 113 | this.textBoxCodeOutput.ReadOnly = true; 114 | this.textBoxCodeOutput.Size = new System.Drawing.Size(213, 38); 115 | this.textBoxCodeOutput.TabIndex = 4; 116 | this.textBoxCodeOutput.TabStop = false; 117 | this.textBoxCodeOutput.Text = "00000000"; 118 | this.textBoxCodeOutput.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; 119 | // 120 | // circularProgressBar 121 | // 122 | this.circularProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 123 | this.circularProgressBar.Location = new System.Drawing.Point(225, 92); 124 | this.circularProgressBar.Name = "circularProgressBar"; 125 | this.circularProgressBar.PathAlpha = 75; 126 | this.circularProgressBar.PathColor = System.Drawing.Color.FromArgb(((int)(((byte)(75)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255))))); 127 | this.circularProgressBar.PathRadius = 39; 128 | this.circularProgressBar.PathWidth = 10; 129 | this.circularProgressBar.ProgressAlpha = 150; 130 | this.circularProgressBar.ProgressAngle = 20; 131 | this.circularProgressBar.ProgressColor = System.Drawing.Color.Navy; 132 | this.circularProgressBar.ProgressInDegree = 180F; 133 | this.circularProgressBar.ProgressRadius = 39; 134 | this.circularProgressBar.ProgressWidth = 15; 135 | this.circularProgressBar.RadiusCalculation = ProgressBar.RadiusCalculation.Auto; 136 | this.circularProgressBar.Size = new System.Drawing.Size(95, 84); 137 | this.circularProgressBar.StartAngle = -90; 138 | this.circularProgressBar.TabIndex = 5; 139 | // 140 | // buttonGenerate 141 | // 142 | this.buttonGenerate.Location = new System.Drawing.Point(224, 83); 143 | this.buttonGenerate.Name = "buttonGenerate"; 144 | this.buttonGenerate.Size = new System.Drawing.Size(120, 23); 145 | this.buttonGenerate.TabIndex = 6; 146 | this.buttonGenerate.Text = "Generate"; 147 | this.buttonGenerate.UseVisualStyleBackColor = true; 148 | this.buttonGenerate.Click += new System.EventHandler(this.button1_Click); 149 | // 150 | // timer1 151 | // 152 | this.timer1.Enabled = true; 153 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 154 | // 155 | // label4 156 | // 157 | this.label4.AutoSize = true; 158 | this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 159 | this.label4.Location = new System.Drawing.Point(194, 49); 160 | this.label4.Name = "label4"; 161 | this.label4.Size = new System.Drawing.Size(24, 16); 162 | this.label4.TabIndex = 7; 163 | this.label4.Text = "T1"; 164 | // 165 | // numericUpDown2 166 | // 167 | this.numericUpDown2.Location = new System.Drawing.Point(224, 45); 168 | this.numericUpDown2.Maximum = new decimal(new int[] { 169 | 3600, 170 | 0, 171 | 0, 172 | 0}); 173 | this.numericUpDown2.Minimum = new decimal(new int[] { 174 | 1, 175 | 0, 176 | 0, 177 | 0}); 178 | this.numericUpDown2.Name = "numericUpDown2"; 179 | this.numericUpDown2.Size = new System.Drawing.Size(120, 20); 180 | this.numericUpDown2.TabIndex = 8; 181 | this.numericUpDown2.Value = new decimal(new int[] { 182 | 30, 183 | 0, 184 | 0, 185 | 0}); 186 | // 187 | // qrCodeImgControl 188 | // 189 | this.qrCodeImgControl.ErrorCorrectLevel = Gma.QrCodeNet.Encoding.ErrorCorrectionLevel.M; 190 | this.qrCodeImgControl.Image = ((System.Drawing.Image)(resources.GetObject("qrCodeImgControl.Image"))); 191 | this.qrCodeImgControl.Location = new System.Drawing.Point(38, 24); 192 | this.qrCodeImgControl.Name = "qrCodeImgControl"; 193 | this.qrCodeImgControl.QuietZoneModule = Gma.QrCodeNet.Encoding.Windows.Render.QuietZoneModules.Two; 194 | this.qrCodeImgControl.Size = new System.Drawing.Size(300, 300); 195 | this.qrCodeImgControl.TabIndex = 9; 196 | this.qrCodeImgControl.TabStop = false; 197 | this.qrCodeImgControl.Text = "qrCodeImgControl1"; 198 | // 199 | // textBoxUser 200 | // 201 | this.textBoxUser.Location = new System.Drawing.Point(50, 396); 202 | this.textBoxUser.Name = "textBoxUser"; 203 | this.textBoxUser.Size = new System.Drawing.Size(300, 20); 204 | this.textBoxUser.TabIndex = 10; 205 | this.textBoxUser.Text = "alice"; 206 | // 207 | // textBoxLable 208 | // 209 | this.textBoxLable.Location = new System.Drawing.Point(50, 365); 210 | this.textBoxLable.Name = "textBoxLable"; 211 | this.textBoxLable.Size = new System.Drawing.Size(300, 20); 212 | this.textBoxLable.TabIndex = 11; 213 | this.textBoxLable.Text = "Example"; 214 | // 215 | // label5 216 | // 217 | this.label5.AutoSize = true; 218 | this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F); 219 | this.label5.Location = new System.Drawing.Point(6, 366); 220 | this.label5.Name = "label5"; 221 | this.label5.Size = new System.Drawing.Size(43, 17); 222 | this.label5.TabIndex = 12; 223 | this.label5.Text = "Lable"; 224 | // 225 | // label6 226 | // 227 | this.label6.AutoSize = true; 228 | this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F); 229 | this.label6.Location = new System.Drawing.Point(6, 397); 230 | this.label6.Name = "label6"; 231 | this.label6.Size = new System.Drawing.Size(38, 17); 232 | this.label6.TabIndex = 13; 233 | this.label6.Text = "User"; 234 | // 235 | // groupBox1 236 | // 237 | this.groupBox1.Controls.Add(this.textBoxLable); 238 | this.groupBox1.Controls.Add(this.label6); 239 | this.groupBox1.Controls.Add(this.textBoxUser); 240 | this.groupBox1.Controls.Add(this.label5); 241 | this.groupBox1.Controls.Add(this.qrCodeImgControl); 242 | this.groupBox1.Location = new System.Drawing.Point(350, 45); 243 | this.groupBox1.Name = "groupBox1"; 244 | this.groupBox1.Size = new System.Drawing.Size(356, 434); 245 | this.groupBox1.TabIndex = 14; 246 | this.groupBox1.TabStop = false; 247 | this.groupBox1.Text = "QR Code"; 248 | // 249 | // groupBox2 250 | // 251 | this.groupBox2.BackColor = System.Drawing.SystemColors.Control; 252 | this.groupBox2.Controls.Add(this.textBoxCodeOutput); 253 | this.groupBox2.Controls.Add(this.circularProgressBar); 254 | this.groupBox2.Location = new System.Drawing.Point(18, 124); 255 | this.groupBox2.Name = "groupBox2"; 256 | this.groupBox2.Size = new System.Drawing.Size(326, 245); 257 | this.groupBox2.TabIndex = 15; 258 | this.groupBox2.TabStop = false; 259 | this.groupBox2.Text = "Code"; 260 | // 261 | // Form1 262 | // 263 | this.ClientSize = new System.Drawing.Size(718, 475); 264 | this.Controls.Add(this.groupBox2); 265 | this.Controls.Add(this.groupBox1); 266 | this.Controls.Add(this.numericUpDown2); 267 | this.Controls.Add(this.label4); 268 | this.Controls.Add(this.buttonGenerate); 269 | this.Controls.Add(this.numericUpDown1); 270 | this.Controls.Add(this.label3); 271 | this.Controls.Add(this.textBoxSecret); 272 | this.Controls.Add(this.label2); 273 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 274 | this.MaximizeBox = false; 275 | this.Name = "Form1"; 276 | this.Text = "TOTP GUI"; 277 | this.Load += new System.EventHandler(this.Form1_Load_1); 278 | ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); 279 | ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndInit(); 280 | ((System.ComponentModel.ISupportInitialize)(this.qrCodeImgControl)).EndInit(); 281 | this.groupBox1.ResumeLayout(false); 282 | this.groupBox1.PerformLayout(); 283 | this.groupBox2.ResumeLayout(false); 284 | this.groupBox2.PerformLayout(); 285 | this.ResumeLayout(false); 286 | this.PerformLayout(); 287 | 288 | } 289 | 290 | #endregion 291 | 292 | 293 | private System.Windows.Forms.Label label1; 294 | private System.Windows.Forms.Label label2; 295 | private System.Windows.Forms.TextBox textBoxSecret; 296 | private System.Windows.Forms.Label label3; 297 | private System.Windows.Forms.NumericUpDown numericUpDown1; 298 | private System.Windows.Forms.TextBox textBoxCodeOutput; 299 | private ProgressBar.CircularProgressBar circularProgressBar; 300 | private System.Windows.Forms.Button buttonGenerate; 301 | private System.Windows.Forms.Timer timer1; 302 | private System.Windows.Forms.Label label4; 303 | private System.Windows.Forms.NumericUpDown numericUpDown2; 304 | private Gma.QrCodeNet.Encoding.Windows.Forms.QrCodeImgControl qrCodeImgControl; 305 | private System.Windows.Forms.TextBox textBoxUser; 306 | private System.Windows.Forms.TextBox textBoxLable; 307 | private System.Windows.Forms.Label label5; 308 | private System.Windows.Forms.Label label6; 309 | private System.Windows.Forms.GroupBox groupBox1; 310 | private System.Windows.Forms.ToolTip toolTip1; 311 | private System.Windows.Forms.GroupBox groupBox2; 312 | } 313 | } 314 | 315 | -------------------------------------------------------------------------------- /TOTPGui/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Windows.Forms; 4 | using ProgressBar; 5 | using TOTP; 6 | 7 | namespace TOTPGui 8 | { 9 | public partial class Form1 : Form 10 | { 11 | private int digit = 6; 12 | private String secret; 13 | private int t1 = 30; 14 | private Totp totp; 15 | 16 | public Form1() 17 | { 18 | InitializeComponent(); 19 | typeof (CircularProgressBar).InvokeMember("DoubleBuffered", 20 | BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, 21 | null, circularProgressBar, new object[] {true}); 22 | } 23 | 24 | private void Form1_Load(object sender, EventArgs e) 25 | { 26 | toolTip1.AutoPopDelay = 5000; 27 | toolTip1.InitialDelay = 1000; 28 | toolTip1.ReshowDelay = 500; 29 | toolTip1.ShowAlways = true; 30 | toolTip1.SetToolTip(qrCodeImgControl, qrCodeImgControl.Text); 31 | } 32 | 33 | private void button1_Click(object sender, EventArgs e) 34 | { 35 | if (Totp.CheckBase32(textBoxSecret.Text)) 36 | { 37 | secret = textBoxSecret.Text; 38 | t1 = (int) numericUpDown2.Value; 39 | digit = (int) numericUpDown1.Value; 40 | totp = new Totp(secret, t1, digit); 41 | qrCodeImgControl.Text = "otpauth://totp/" + textBoxLable.Text + ":" + textBoxUser.Text + "?secret=" + 42 | textBoxSecret.Text + "&issuer=" + textBoxLable.Text; 43 | toolTip1.SetToolTip(qrCodeImgControl, qrCodeImgControl.Text); 44 | } 45 | else 46 | { 47 | MessageBox.Show("The secret is not Base32 encoded", "TOTP GUI", MessageBoxButtons.OK, 48 | MessageBoxIcon.Error); 49 | } 50 | } 51 | 52 | private void timer1_Tick(object sender, EventArgs e) 53 | { 54 | var unixTimestamp = (UInt64) (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 55 | var tmp = ((unixTimestamp%(UInt64) t1) + 1)/(double) t1*360; 56 | circularProgressBar.ProgressAngle = (int) tmp; 57 | if (totp != null) 58 | { 59 | var code = totp.getCodeString(); 60 | if (!textBoxCodeOutput.Text.Equals(code)) 61 | textBoxCodeOutput.Text = code; 62 | } 63 | } 64 | 65 | private void Form1_Load_1(object sender, EventArgs e) 66 | { 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /TOTPGui/Form1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 125 | 126 | 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 224 | maL2hClqZYpamaL2hF9DbyCfjnaWbeonammZovaEKWplilqZovaEX0NvIJ+OdpZt6idqaZmi9oQpamWK 225 | Wpmi9oRfQ28gn452lm3qJ2ppmaL2hClqZYpamaL2hF9DbyCfjnaWbeonammZovaEKWplilqZovaEX0Nv 226 | IJ+OdpZt6idqafkWdDfZRjNkilrZRjNkitqJKWrl09HOsk39RC0t34LuJttohkxRK9tohkxROzFFrXw6 227 | 2lm2qZ+opeVb0N1kG82QKWplG82QKWonpqiVT0c7yzb1E7W0fAu6m2yjGTJFrWyjGTJF7cQUtfLpaGfZ 228 | pn6ilpZvQXeTbTRDpqiVbTRDpqidmKJWPh3tLNvUT9TS8i3obrKNZsgUtbKNZsgUtRNT1Mqno51lm/qJ 229 | Wlq+Bd1NttEMmaJWttEMmaJ2Yopa+XS0s2xTP1FLy7egu8k2miFT1Mo2miFT1E5MUSufjnaWbeonamn5 230 | FnQ32UYzZIpa2UYzZIraiSlq5dPRzrJN/UQtLd+C7ibbaIZMUSvbaIZMUTsxRa18OtpZtqmfqKXX5/+H 231 | 1gy5zNCbTkxRO7FN/UQtvfb/w7TRDLnM0JtOTFE7sU39RC299v/DtNEMuczQm05MUTuxTf1ELb32/8O0 232 | 0Qy5zNCbTkxRO7FN/UQtvfb/w7TRDLnM0JtOTFE7sU39RC299v/DtNEMuczQm05MUTuxTf1ELb32/8O0 233 | 0Qy5zNCbTkxRO7FN/UQtvfb/w7TRDLnM0JtOTFE7sU39RC299v/DtNEMuczQm05MUTuxTf1ELb32/8O0 234 | 0Qy5zNCbTkxRO7HN/s9aluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6 235 | +yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6+yFaluU6 236 | +yFaluU6+yFaluUy//33f/P8nny8+DhbAAAAAElFTkSuQmCC 237 | 238 | 239 | 240 | 104, 17 241 | 242 | -------------------------------------------------------------------------------- /TOTPGui/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("TOTPGui")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TOTPGui")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("47c10189-ed91-4bd6-a3e2-d2f86f49a5a3")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /TOTPGui/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TOTPGui.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TOTPGui.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /TOTPGui/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /TOTPGui/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TOTPGui.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TOTPGui/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TOTPGui/TOTPGui.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace TOTPGui 5 | { 6 | internal static class TOTPGui 7 | { 8 | [STAThread] 9 | private static void Main() 10 | { 11 | Application.EnableVisualStyles(); 12 | Application.SetCompatibleTextRenderingDefault(false); 13 | Application.Run(new Form1()); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /TOTPGui/TOTPGui.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {047D1B1F-F3D5-4BE9-91D0-F86F8855B41E} 8 | WinExe 9 | Properties 10 | TOTPGui 11 | TOTPGui 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | D:\libs\CirculaProgressBarCSharp\CircularProgressBar.dll 37 | 38 | 39 | D:\libs\QrCode.Net 0.4 Pre-Release\Gma.QrCodeNet.Encoding.Net45\Gma.QrCodeNet.Encoding.Net45.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Form 55 | 56 | 57 | Form1.cs 58 | 59 | 60 | 61 | 62 | Form1.cs 63 | 64 | 65 | ResXFileCodeGenerator 66 | Resources.Designer.cs 67 | Designer 68 | 69 | 70 | True 71 | Resources.resx 72 | 73 | 74 | SettingsSingleFileGenerator 75 | Settings.Designer.cs 76 | 77 | 78 | True 79 | Settings.settings 80 | True 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | {2c51fae6-7f0f-43cc-9eec-d66958bf99b2} 89 | TOTPLib 90 | 91 | 92 | 93 | 100 | -------------------------------------------------------------------------------- /TOTPTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("TOTPTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TOTPTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("4cae9012-f3e4-4ec9-8a95-600beaa3ee72")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /TOTPTests/TOTPTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {DF2DF9D8-9546-4126-AB8B-D6654FA0075F} 7 | Library 8 | Properties 9 | TOTPTests 10 | TOTPTests 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {2C51FAE6-7F0F-43CC-9EEC-D66958BF99B2} 59 | TOTPLib 60 | 61 | 62 | 63 | 64 | 65 | 66 | False 67 | 68 | 69 | False 70 | 71 | 72 | False 73 | 74 | 75 | False 76 | 77 | 78 | 79 | 80 | 81 | 82 | 89 | -------------------------------------------------------------------------------- /TOTPTests/TotpTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace TOTP.Tests 4 | { 5 | [TestClass] 6 | public class TotpTests 7 | { 8 | [TestMethod] 9 | public void FromBase32StringTest() 10 | { 11 | byte[] data = 12 | { 13 | 0xec, 0x02, 0x9b, 0x80, 0x27, 0x9d, 0x19, 0x25, 0x86, 0x03, 0x97, 0xb5, 0x65, 0x4c, 0x8c, 14 | 0x6d, 0x0b, 0xb8, 0x2e, 0x63 15 | }; 16 | var database32 = "5QBJXABHTUMSLBQDS62WKTEMNUF3QLTD"; 17 | var dut = new Totp(database32); 18 | CollectionAssert.AreEqual(data, dut.key); 19 | } 20 | 21 | [TestMethod] 22 | public void getCodeTest() 23 | { 24 | var secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; 25 | var dut = new Totp(secret, 30, 8); 26 | Assert.AreEqual(94287082, dut.getCode(59)); 27 | Assert.AreEqual(7081804, dut.getCode(1111111109)); 28 | Assert.AreEqual(14050471, dut.getCode(1111111111)); 29 | Assert.AreEqual(89005924, dut.getCode(1234567890)); 30 | Assert.AreEqual(69279037, dut.getCode(2000000000)); 31 | Assert.AreEqual(65353130, dut.getCode(20000000000)); 32 | } 33 | 34 | [TestMethod] 35 | public void getCodeStringTest() 36 | { 37 | var secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; 38 | var dut = new Totp(secret, 30, 8); 39 | Assert.AreEqual("94287082", dut.getCodeString(59)); 40 | Assert.AreEqual("07081804", dut.getCodeString(1111111109)); 41 | Assert.AreEqual("14050471", dut.getCodeString(1111111111)); 42 | Assert.AreEqual("89005924", dut.getCodeString(1234567890)); 43 | Assert.AreEqual("69279037", dut.getCodeString(2000000000)); 44 | Assert.AreEqual("65353130", dut.getCodeString(20000000000)); 45 | 46 | dut = new Totp(secret, 30, 6); 47 | Assert.AreEqual("287082", dut.getCodeString(59)); 48 | Assert.AreEqual("081804", dut.getCodeString(1111111109)); 49 | Assert.AreEqual("050471", dut.getCodeString(1111111111)); 50 | Assert.AreEqual("005924", dut.getCodeString(1234567890)); 51 | Assert.AreEqual("279037", dut.getCodeString(2000000000)); 52 | Assert.AreEqual("353130", dut.getCodeString(20000000000)); 53 | } 54 | } 55 | } --------------------------------------------------------------------------------