├── .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 | iVBORw0KGgoAAAANSUhEUgAAASIAAAEiCAYAAABdvt+2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
127 | YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAABmBSURBVHhe7dTBjiS7jgTR/v+fvrN5yzOAA/SSIiNogKFX
128 | JlLKrvj337Isy2X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2
129 | Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2Q7Qsy3X2
130 | Q7Qsy3XqH6J///6t8C3obhNT1Mo2mrH+wTv/798aWnrdD9H/Z4pa2UYz1v0Q/axvQXebmKJWttGMdT9E
131 | P+tb0N0mpqiVbTRj3Q/Rz/oWdLeJKWplG81Y90P0s74F3W1iilrZRjPW/RD9rG9Bd5uYola20Yx1P0Q/
132 | 61vQ3SamqJVtNGPdD9HP+hZ0t4kpamUbzVj3Q/SzvgXdbWKKWtlGM9YXfYjegu4mb6FdZBvNeJIpauVb
133 | 0N1km/qJWlq+Bd1N3kK7yDaa8SRT1Mq3oLvJNvUTtbR8C7qbvIV2kW0040mmqJVvQXeTbeonamn5FnQ3
134 | eQvtIttoxpNMUSvfgu4m29RP1NLyLehu8hbaRbbRjCeZola+Bd1NtqmfqKXlW9Dd5C20i2yjGU8yRa18
135 | C7qbbFM/UUvLt6C7yVtoF9lGM55kilr5FnQ32aZ+opaWb0F3k7fQLrKNZjzJFLXyLehusk39RC0t34Lu
136 | Jm+hXWQbzXiSKWrlW9DdZJv6iVpavgXdTd5Cu8g2mvEkU9TKt6C7yTb1E7W0TFF7whS1MkWtTFErU9RO
137 | TFEr22iGTFF7whS1sk39RC0tU9SeMEWtTFErU9TKFLUTU9TKNpohU9SeMEWtbFM/UUvLFLUnTFErU9TK
138 | FLUyRe3EFLWyjWbIFLUnTFEr29RP1NIyRe0JU9TKFLUyRa1MUTsxRa1soxkyRe0JU9TKNvUTtbRMUXvC
139 | FLUyRa1MUStT1E5MUSvbaIZMUXvCFLWyTf1ELS1T1J4wRa1MUStT1MoUtRNT1Mo2miFT1J4wRa1sUz9R
140 | S8sUtSdMUStT1MoUtTJF7cQUtbKNZsgUtSdMUSvb1E/U0jJF7QlT1MoUtTJFrUxROzFFrWyjGTJF7QlT
141 | 1Mo29RO1tExRe8IUtTJFrUxRK1PUTkxRK9tohkxRe8IUtbJN/UQtLVPUnjBFrUxRK1PUyhS1E1PUyjaa
142 | IVPUnjBFrWxTP1FLyxS1J0xRK1PUyhS1J0xRe8IUtTJF7QlT1Mo29RO1tExRe8IUtTJFrUxRe8IUtSdM
143 | UStT1J4wRa1sUz9RS8sUtSdMUStT1MoUtSdMUXvCFLUyRe0JU9TKNvUTtbRMUXvCFLUyRa1MUXvCFLUn
144 | TFErU9SeMEWtbFM/UUvLFLUnTFErU9TKFLUnTFF7whS1MkXtCVPUyjb1E7W0TFF7whS1MkWtTFF7whS1
145 | J0xRK1PUnjBFrWxTP1FLyxS1J0xRK1PUyhS1J0xRe8IUtTJF7QlT1Mo29RO1tExRe8IUtTJFrUxRe8IU
146 | tSdMUStT1J4wRa1sUz9RS8sUtSdMUStT1MoUtSdMUXvCFLUyRe0JU9TKNvUTtbRMUXvCFLUyRa1MUXvC
147 | FLUnTFErU9SeMEWtbFM/UUvLFLUnTFErU9ROTFErv4beQKaoPWGKWtmmfqKWlilqT5iiVqaonZiiVn4N
148 | vYFMUXvCFLWyTf1ELS1T1J4wRa1MUTsxRa38GnoDmaL2hClqZZv6iVpapqg9YYpamaJ2Yopa+TX0BjJF
149 | 7QlT1Mo29RO1tExRe8IUtTJF7cQUtfJr6A1kitoTpqiVbeonammZovaEKWplitqJKWrl19AbyBS1J0xR
150 | K9vUT9TSMkXtCVPUyhS1E1PUyq+hN5Apak+Yola2qZ+opWWK2hOmqJUpaiemqJVfQ28gU9SeMEWtbFM/
151 | UUvLFLUnTFErU9ROTFErv4beQKaoPWGKWtmmfqKWlilqT5iiVqaonZiiVn4NvYFMUXvCFLWyTf1ELS3f
152 | gu4mU9TKNpohb6FdZBvNkG9Bd5Nt6idqafkWdDeZola20Qx5C+0i22iGfAu6m2xTP1FLy7egu8kUtbKN
153 | ZshbaBfZRjPkW9DdZJv6iVpavgXdTaaolW00Q95Cu8g2miHfgu4m29RP1NLyLehuMkWtbKMZ8hbaRbbR
154 | DPkWdDfZpn6ilpZvQXeTKWplG82Qt9Auso1myLegu8k29RO1tHwLuptMUSvbaIa8hXaRbTRDvgXdTbap
155 | n6il5VvQ3WSKWtlGM+QttItsoxnyLehusk39RC0t34LuJlPUyjaaIW+hXWQbzZBvQXeTbeonamn5FnQ3
156 | maJWttEMeQvtIttohnwLuptsUz9RS6/5M6uVKWplilqZolamqJUpatf8/VLqJ2rp9Xt/mClqZYpamaJ2
157 | zd8vpX6ill6/94eZolamqJUpatf8/VLqJ2rp9Xt/mClqZYpamaJ2zd8vpX6ill6/94eZolamqJUpatf8
158 | /VLqJ2rp9Xt/mClqZYpamaJ2zd8vpX6ill6/94eZolamqJUpatf8/VLqJ2rp9Xt/mClqZYpamaJ2zd8v
159 | pX6ill6/94eZolamqJUpatf8/VLqJ2rp9Xt/mClqZYpamaJ2zd8vpX/iMkI/umyjGbKNZpxweRb7izwM
160 | /dHINpoh22jGCZdnsb/Iw9AfjWyjGbKNZpxweRb7izwM/dHINpoh22jGCZdnsb/Iw9AfjWyjGbKNZpxw
161 | eRb7izwM/dHINpoh22jGCZdnsb/Iw9AfjWyjGbKNZpxweRb7izwM/dHINpoh22jGCZdnsb/Iw9AfjWyj
162 | GbKNZpxweRb7izwM/dHINpoh22jGCZdnUf9F9KPLFLW/6NPRzvJr6A1+0aezH6JDPh3tLL+G3uAXfTr7
163 | ITrk09HO8mvoDX7Rp7MfokM+He0sv4be4Bd9OvshOuTT0c7ya+gNftGnsx+iQz4d7Sy/ht7gF306+yE6
164 | 5NPRzvJr6A1+0aezH6JDPh3tLL+G3uAXfTr7ITrk09HO8mvoDX7Rp7MfokM+He0sv4be4Bd9Op/7EN1C
165 | u8i3oLtNTFErU9ROTFEr22iGbFM/UUvLFLUTb6Fd5FvQ3SamqJUpaiemqJVtNEO2qZ+opWWK2om30C7y
166 | LehuE1PUyhS1E1PUyjaaIdvUT9TSMkXtxFtoF/kWdLeJKWplitqJKWplG82QbeonammZonbiLbSLfAu6
167 | 28QUtTJF7cQUtbKNZsg29RO1tExRO/EW2kW+Bd1tYopamaJ2Yopa2UYzZJv6iVpapqideAvtIt+C7jYx
168 | Ra1MUTsxRa1soxmyTf1ELS1T1E68hXaRb0F3m5iiVqaonZiiVrbRDNmmfqKWlilqJ95Cu8i3oLtNTFEr
169 | U9ROTFEr22iGbFM/UUvLFLUTb6Fd5FvQ3SamqJUpaiemqJVtNEO26Z8YosvJNpohU9TKt6C7/aIpak+Y
170 | ovaEba79hehyso1myBS18i3obr9oitoTpqg9YZtrfyG6nGyjGTJFrXwLutsvmqL2hClqT9jm2l+ILifb
171 | aIZMUSvfgu72i6aoPWGK2hO2ufYXosvJNpohU9TKt6C7/aIpak+YovaEba79hehyso1myBS18i3obr9o
172 | itoTpqg9YZtrfyG6nGyjGTJFrXwLutsvmqL2hClqT9jm2l+ILifbaIZMUSvfgu72i6aoPWGK2hO2ufYX
173 | osvJNpohU9TKt6C7/aIpak+YovaEba79hehyso1myBS18i3obr9oitoTpqg9YZtrfyG63MQUtfIt6G4y
174 | Re3ENpoxMUWtXMy1l9GPNDFFrXwLuptMUTuxjWZMTFErF3PtZfQjTUxRK9+C7iZT1E5soxkTU9TKxVx7
175 | Gf1IE1PUyregu8kUtRPbaMbEFLVyMddeRj/SxBS18i3objJF7cQ2mjExRa1czLWX0Y80MUWtfAu6m0xR
176 | O7GNZkxMUSsXc+1l9CNNTFEr34LuJlPUTmyjGRNT1MrFXHsZ/UgTU9TKt6C7yRS1E9toxsQUtXIx115G
177 | P9LEFLXyLehuMkXtxDaaMTFFrVzMtZfRjzQxRa18C7qbTFE7sY1mTExRKxdTfxk9vkxRK2+hXZ5kitqJ
178 | KWplG82YmKL2hClqZZv6iVpapqiVt9AuTzJF7cQUtbKNZkxMUXvCFLWyTf1ELS1T1MpbaJcnmaJ2Yopa
179 | 2UYzJqaoPWGKWtmmfqKWlilq5S20y5NMUTsxRa1soxkTU9SeMEWtbFM/UUvLFLXyFtrlSaaonZiiVrbR
180 | jIkpak+Yola2qZ+opWWKWnkL7fIkU9ROTFEr22jGxBS1J0xRK9vUT9TSMkWtvIV2eZIpaiemqJVtNGNi
181 | itoTpqiVbeonammZolbeQrs8yRS1E1PUyjaaMTFF7QlT1Mo29RO1tExRK2+hXZ5kitqJKWplG82YmKL2
182 | hClqZZv6iVpapqiVt9AuTzJF7cQUtbKNZkxMUXvCFLWyTf1ELS0Xo7eSi9FbyTaaIdtoxsRb1CfrcnIx
183 | eiu5GL2VbKMZso1mTLxFfbIuJxejt5KL0VvJNpoh22jGxFvUJ+tycjF6K7kYvZVsoxmyjWZMvEV9si4n
184 | F6O3kovRW8k2miHbaMbEW9Qn63JyMXoruRi9lWyjGbKNZky8RX2yLicXo7eSi9FbyTaaIdtoxsRb1Cfr
185 | cnIxeiu5GL2VbKMZso1mTLxFfbIuJxejt5KL0VvJNpoh22jGxFvUJ+tycjF6K7kYvZVsoxmyjWZMvEV9
186 | si4nU9TKFLUyRa28hXY5YRvNkClqZYpa2UYzTtimfqKWlilqZYpamaJW3kK7nLCNZsgUtTJFrWyjGSds
187 | Uz9RS8sUtTJFrUxRK2+hXU7YRjNkilqZola20YwTtqmfqKVlilqZolamqJW30C4nbKMZMkWtTFEr22jG
188 | CdvUT9TSMkWtTFErU9TKW2iXE7bRDJmiVqaolW0044Rt6idqaZmiVqaolSlq5S20ywnbaIZMUStT1Mo2
189 | mnHCNvUTtbRMUStT1MoUtfIW2uWEbTRDpqiVKWplG804YZv6iVpapqiVKWplilp5C+1ywjaaIVPUyhS1
190 | so1mnLBN/UQtLVPUyhS1MkWtvIV2OWEbzZApamWKWtlGM07Ypn6ilpYpamWKWpmiVt5Cu5ywjWbIFLUy
191 | Ra1soxknbFM/UUvLW2iXiW00Y2KKWtlGM2QbzZApaie20YyJbeonaml5C+0ysY1mTExRK9tohmyjGTJF
192 | 7cQ2mjGxTf1ELS1voV0mttGMiSlqZRvNkG00Q6aondhGMya2qZ+opeUttMvENpoxMUWtbKMZso1myBS1
193 | E9toxsQ29RO1tLyFdpnYRjMmpqiVbTRDttEMmaJ2YhvNmNimfqKWlrfQLhPbaMbEFLWyjWbINpohU9RO
194 | bKMZE9vUT9TS8hbaZWIbzZiYola20QzZRjNkitqJbTRjYpv6iVpa3kK7TGyjGRNT1Mo2miHbaIZMUTux
195 | jWZMbFM/UUvLW2iXiW00Y2KKWtlGM2QbzZApaie20YyJbeonaml5C+0ysY1mTExRK9tohmyjGTJF7cQ2
196 | mjGxTf1ELS1T1MoUtSdMUSvbaIa8hXZZc1PUyjb1E7W0TFErU9SeMEWtbKMZ8hbaZc1NUSvb1E/U0jJF
197 | rUxRe8IUtbKNZshbaJc1N0WtbFM/UUvLFLUyRe0JU9TKNpohb6Fd1twUtbJN/UQtLVPUyhS1J0xRK9to
198 | hryFdllzU9TKNvUTtbRMUStT1J4wRa1soxnyFtplzU1RK9vUT9TSMkWtTFF7whS1so1myFtolzU3Ra1s
199 | Uz9RS8sUtTJF7QlT1Mo2miFvoV3W3BS1sk39RC0tU9TKFLUnTFEr22iGvIV2WXNT1Mo29RO1tExRK1PU
200 | njBFrWyjGfIW2mXNTVEr29z7n7UQ/egnTFF7whS18hbaRbbRDHmLe5MXov8cJ0xRe8IUtfIW2kW20Qx5
201 | i3uTF6L/HCdMUXvCFLXyFtpFttEMeYt7kxei/xwnTFF7whS18hbaRbbRDHmLe5MXov8cJ0xRe8IUtfIW
202 | 2kW20Qx5i3uTF6L/HCdMUXvCFLXyFtpFttEMeYt7kxei/xwnTFF7whS18hbaRbbRDHmLe5MXov8cJ0xR
203 | e8IUtfIW2kW20Qx5i3uTF6L/HCdMUXvCFLXyFtpFttEMeYt7kxei/xwnTFF7whS18hbaRbbRDHmL+mRd
204 | bv3gfyzsMjFFrUxRK1PUTkxRO7FN/UQtvf7BD4cZ8hbaZWKKWpmiVqaonZiidmKb+olaev2DHw4z5C20
205 | y8QUtTJFrUxROzFF7cQ29RO19PoHPxxmyFtol4kpamWKWpmidmKK2olt6idq6fUPfjjMkLfQLhNT1MoU
206 | tTJF7cQUtRPb1E/U0usf/HCYIW+hXSamqJUpamWK2okpaie2qZ+opdc/+OEwQ95Cu0xMUStT1MoUtRNT
207 | 1E5sUz9RS69/8MNhhryFdpmYolamqJUpaiemqJ3Ypn6ill7/4IfDDHkL7TIxRa1MUStT1E5MUTuxTf1E
208 | Lb3+wQ+HGfIW2mViilqZolamqJ2YonZim/qJWlq+Bd1NpqiVt9AuE9tohryFdpFtNGNim/qJWlq+Bd1N
209 | pqiVt9AuE9tohryFdpFtNGNim/qJWlq+Bd1NpqiVt9AuE9tohryFdpFtNGNim/qJWlq+Bd1NpqiVt9Au
210 | E9tohryFdpFtNGNim/qJWlq+Bd1NpqiVt9AuE9tohryFdpFtNGNim/qJWlq+Bd1NpqiVt9AuE9tohryF
211 | dpFtNGNim/qJWlq+Bd1NpqiVt9AuE9tohryFdpFtNGNim/qJWlq+Bd1NpqiVt9AuE9tohryFdpFtNGNi
212 | m/qJWlq+Bd1NpqiVt9AuE9tohryFdpFtNGNim/qJWlq+Bd1NpqiVt9AuE9tohryFdpFtNGNim/qJWlqm
213 | qD1hilqZovaEKWplitq1b4pa2aZ+opaWKWpPmKJWpqg9YYpamaJ27ZuiVrapn6ilZYraE6aolSlqT5ii
214 | VqaoXfumqJVt6idqaZmi9oQpamWK2hOmqJUpate+KWplm/qJWlqmqD1hilqZovaEKWplitq1b4pa2aZ+
215 | opaWKWpPmKJWpqg9YYpamaJ27ZuiVrapn6ilZYraE6aolSlqT5iiVqaoXfumqJVt6idqaZmi9oQpamWK
216 | 2hOmqJUpate+KWplm/qJWlqmqD1hilqZovaEKWplitq1b4pa2aZ+opaWKWpPmKJWpqg9YYpamaJ27Zui
217 | Vrapn6ilZYraE6aolSlq5dfQG8gUtRNT1Mo2mjGxTf1ELS1T1J4wRa1MUSu/ht5ApqidmKJWttGMiW3q
218 | J2ppmaL2hClqZYpa+TX0BjJF7cQUtbKNZkxsUz9RS8sUtSdMUStT1MqvoTeQKWonpqiVbTRjYpv6iVpa
219 | pqg9YYpamaJWfg29gUxROzFFrWyjGRPb1E/U0jJF7QlT1MoUtfJr6A1kitqJKWplG82Y2KZ+opaWKWpP
220 | mKJWpqiVX0NvIFPUTkxRK9toxsQ29RO1tExRe8IUtTJFrfwaegOZonZiilrZRjMmtqmfqKVlitoTpqiV
221 | KWrl19AbyBS1E1PUyjaaMbFN/UQtLVPUnjBFrUxRK7+G3kCmqJ2Yola20YyJbeonammZovaEKWplilqZ
222 | ovaEX0NvIJ+OdpZt6idqaZmi9oQpamWKWpmi9oRfQ28gn452lm3qJ2ppmaL2hClqZYpamaL2hF9DbyCf
223 | jnaWbeonammZovaEKWplilqZovaEX0NvIJ+OdpZt6idqaZmi9oQpamWKWpmi9oRfQ28gn452lm3qJ2pp
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 | }
--------------------------------------------------------------------------------