Open shahareldad opened 3 years ago
Hey - just reading through the code snippet, I see that you are generating and emailing a code to the user here - why exctly are you doing that? You should never need to generate a code yourself, the DefaultCodeGenerator
is only used by other classes in the library to verify codes. The codes are generated by the MFA app on your phone.
An example flow would be:
1) Generate a secret and create a QR code from it (as you are doing) 2) Have the MFA app on your phone scan the QR code. 3) The MFA app will now be generating codes every 60 seconds for the secret. 4) You can try entering one of these app generated codes into a servlet that verifies it (as you are doing)
I would also get the code from the query string by doing request.getParameter('code')
rather than doing string manipulation on the URL.
Hope this helps
Some of the users who will be using our web app will not have smart phones (per their religion) and the best I can do is send the code to their work email so they can enter it back to the web app for verification. This is why I want to generate code and send it to their email and when they enter it back I will verify it.
The main issue in my code is that I couldn't generate a code similar to my app on my smart phone. The secondary issue was that I'm missing something in the code to verify it.
I'm new to Java so I have some learning curve but I already solved the request.getParameter('code') part
Thanks
I see - okay I understand the use case. The problem does indeed lie with the second parameter passed into the generate
method on the CodeGenerator
. This param is the current "time bucket" counter - which is basically the number of full 60 seconds (as that is the time period you are using) since Jan 1st 1970, 00:00.
You can see how the library calculates and uses this counter number on this line in the DefaultCodeVerifier
: https://github.com/samdjstevens/java-totp/blob/master/totp/src/main/java/dev/samstevens/totp/code/DefaultCodeVerifier.java#L30
So what you will need to do is replace the 1
with Math.floorDiv(timeProvider.getTime(), 60)
(move the instantiation of SystemTimeProvider
object up a bit so you have access to it here).
That should then start generating valid codes.
Thanks I will try that at work on Sunday and let you know.
Hi
It failed to work. I moved the timeProvider as you suggested and sent Math.floorDiv(timeProvider.getTime(), 60)
Here is the updated code:
`
CodeGenerator codeGenerator = new DefaultCodeGenerator(HashingAlgorithm.SHA256);
// ========================================
// Generating a code to email the user
// ========================================
TimeProvider timeProvider = new SystemTimeProvider();
try {
String codeToCheck = codeGenerator.generate(secret, Math.floorDiv(timeProvider.getTime(), 60)); // what should come here instead of the "1"
// codeToCheck is never the ok - I guess because of the second parameter which I don't know what to send.
response.getWriter().append("\r\nCode generated: " + codeToCheck);//.append(request.getContextPath());
} catch (CodeGenerationException ex){
ex.printStackTrace();
}
// ========================================
// Getting code from the url and checking it
// ========================================
String code = request.getParameter("code");
response.getWriter().append("\r\nCode from request: " + code);//.append(request.getContextPath());
DefaultCodeVerifier verifier = new DefaultCodeVerifier(codeGenerator, timeProvider);
verifier.setTimePeriod(60);
verifier.setAllowedTimePeriodDiscrepancy(2);
// secret = the shared secret for the user
// code = the code submitted by the user
boolean successful = verifier.isValidCode(secret, code);
if (successful) System.out.println(successful);
response.getWriter().append("\r\nIs code verified: " + successful);//.append(request.getContextPath());
`
Math.floorDiv(timeProvider.getTime(), 60)
I had same requirements, this worked for me, thank you
Hi
Sorry for asking here if it's not the place but I tried stackoverflow with no response. I'm trying to validate a token generated by an App (FortiToken Mobile if it matters) but the validator keeps returning false to me. I went over the usage section in the home page here several times but I can't see what I missed. Here is the code I play with - It has the qr code generation, validation, and trying to get a token so I can email the user for him to enter it back.
Any help/direction would be great Thanks
`
`