One time password(OTP) is one of the common forms of Multi-Factor
Authentication present on most web applications today. In this tutorial, we
will give an overview of how TOTP works and then guide you through
implementing an iOS authenticator application to generate the TOTP and share
it to a nearby web application using Chirp.

Here’s the full project in action

Background

Using just a “shared secret” as a form of authentication is vulnerable to
replay attacks. A replay attack is a version of the “Man in the middle”
attacks. It is an attack on the network where the hashed shared secret sent
across the network is intercepted and reused to gain access.

TOTP (Time-based OTP) is an open standard algorithm that computes a one-
time password using a combination of a secret key, shared between a client and
the server, and the time. This prevents the user from memorizing the shared
secret and makes it difficult for a replay attack, as the pin changes with
time.

TOTP is an extension of HOTP (HMAC based one time passwords) explained in detail below. For both HOTP and TOTP, a shared base-32 secret key is generated between the client and the server. This key is encoded with a message (in our case is the timestamp) to form the HMAC-SHA1 cryptographic hash payload. TOTP uses the UNIX epoch as the time, formatted in seconds. By default, we refresh the TOTP every 30 seconds. This starts at the top of the minute(xx:xx:00) and 30 seconds after the minute (xx:xx:30).

Let us try to understand how the TOTP is obtained from the HMAC-SHA-1
generated pin. An example to generate the pin using OpenSSL on a MacOS
terminal is shown below.

$ KEY=`openssl rand -hex 16`  
$ echo $KEY  
9925d82b3b7f87326e1552f74592bed8  
$ date +%s | openssl sha1 -hmac “$KEY”  
b3c377e581fff1119ae11384481ad95712da1510  
$ date +%s | openssl sha1 -hmac “$KEY” # After 30 Seconds  
528c777129d1ed11ed1bcd92e03495fec2332daf

We generate a random hex string as the key, the unix epoch time is obtained
using date + %s. Here we obtain the HMAC-SHA-1 string as
“b3c377e581fff1119ae11384481ad95712da1510”. We notice that we obtain a
40-character hexadecimal string.

Dynamic Truncation is performed next to convert this long string into
something smaller and more secure. In dynamic truncation we look at the last
character of this string, that is the number ‘0’, highlighted below.

To determine the truncation, we use the last character as the starting index
of our string. In our example, the hexadecimal character ‘0’ when converted to
decimal is also ‘0’. So starting with the 0th Index we read the next 31-bits
to obtain our dynamically truncated string.

From the original HMAC-SHA-1 hash of “b3c377e581fff1119ae11384481ad95712da1510”, we have dynamically truncated it to “B3C377E5”.

The final step to obtain the pin is to convert this truncated string into a
‘decimal’. We can do it on the terminal by running the commands below.

$ echo “ibase=16; B3C377E5” | bc  
3015931877

Finally, we pick the required number of digits needed for the pin from this
decimal value. If we need 6 digits, we modulo 1,000,000 and we get the last 6
digits and we end up with TOTP = 931877

What are we trying to accomplish?

The procedure for generation of TOTP pin is automated. The verification the of
TOTP pin is automated. But we still manually input the pin digits every single time. There are instances where we type in a couple of digits and the PIN changes (Oh! drat).

Our mission at Chirp is to make everyday tasks like this simpler. Tasks that are frustrating for humans but easy for machines.

Building the Chirp + TOTP iOS Application

The Chirp Connect SDK enables your apps to send and receive data using sound.
The Chirp Connect SDK encodes the generated TOTP as an audio signal and then
transmits it to the web application.

Before we begin, let’s make sure we have the following set up.

Xcode
Install from the App Store

Chirp iOS SDK
Sign up for it here

We will develop the application using Objective-C , start by setting up
the project.

  1. Create an Xcode project.
  2. Download the latest Chirp iOS SDK from here
  3. Follow steps at the Chirp Developers Page to integrate Chirp into Xcode. This involves importing the framework and updating your info.plist file to include microphone usage.
  4. With the above completed, we are all set to start coding the application. Start by initialising the Chirp Connect in the viewDidLoad method. Chirp Developer Hub should provide your appropriate key and secret.
self.connect = [[ChirpConnect alloc] initWithAppKey:CHIRP_APP_KEY andSecret:CHIRP_APP_SECRET];

[self.connect getLicenceStringWithCompletion:^(NSString * _Nullable licence, NSError * _Nullable error)   
{  
   // set the licence  
   NSError *licenceError = [self.connect setLicenceString:licence];


   // start the SDK  
   NSError *startError = [self.connect start];  
}];

5. To begin the integration, we would need the following classes,
a. Base32Additions — Needed to generate an HMAC-SHA-1 value of the secret
key.
b. OTPGenerator — Needed to generate the PIN.
c. TOTPGenerator—An extension of the OTPGenerator class which utilises the
Timestamp to generate the PIN.
Drag and drop the Classes folder from this
repository into to your project.

This consists of the required Base32 additions for NSString and NSData
as well as the barebones google-authenticator classes from the opensource Google repo.
NOTE: Classes obtained from b and c are not ARC-compliant so you would have to set the Objective-C Automatic Reference Counting flag to NO in the Project Build Settings.

Before, we write the function to utilise the aforementioned classes and
generate our PIN.
We need to calculate the timestamp using details from the inbuilt NSDate
class, we can write the following function to obtain that

- (NSTimeInterval)calculateTimeInterval  
{  
    NSDate *now = [NSDate date];  
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];  
    [dateFormatter setDateFormat:@”yyyy-MM-dd HH:mm:ss”];  
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:@”GMT”];  
    [dateFormatter setTimeZone:timeZone];


    long timestamp = (long)[now timeIntervalSince1970];  
    if(timestamp % [self.expiryTextField.text integerValue] != 0)  
    {  
       timestamp -= timestamp % [self.expiryTextField.text integerValue];  
    }


    return ([[NSString stringWithFormat:@”%ld”,timestamp] integerValue]);  
}

Perform the Base32 Encoding on our shared secret key and pass it onto the TOTP
Generator along with the calculated timestamp

- (void)generatePIN  
{  
   NSString *secret = YOUR_SHARED_SECRET;  
   NSData *secretData = [NSData dataWithBase32String:[secret base32String]];


   NSTimeInterval timestamp = [self calculateTimeInterval];


   TOTPGenerator *generator = [[TOTPGenerator alloc] initWithSecret:secretData algorithm:kOTPGeneratorSHA1Algorithm digits:YOUR_NUM_DIGITS period:YOUR_REFRESH_PERIOD];  
   
   NSString *pin = [generator generateOTPForDate:[NSDate dateWithTimeIntervalSince1970:timestamp]];  
}

Chirp payloads are byte arrays represented by the NSData type. Since our
generated PIN is an NSString object, we need to create a method to encode
the message.

-(NSData *) encodeMessage:(NSString *)message  
{  
   NSString *string = [NSString stringWithUTF8String:message.UTF8String];  
   if ([string lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > [self.connect maxPayloadLength])   
   {  
      return nil;  
   }  
   else   
   {  
      NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];  
      return [self.connect isValidPayload:stringData] ? stringData : nil;  
   }  
}

Now we are ready to send the PIN, lets create a button to send the PIN as a
sequence of tones using Chirp.

- (IBAction)sendButtonPressed:(id)sender  
{  
   NSString *chirpPIN = self.PINLabel.text;  
   NSData *data = [self encodeMessage:chirpPIN];  
   [self.connect send:data];  
}

And voila! You should now have a simple application through which you can
generate a TOTP PIN based on your secret key and transmit it over to the web
application with the click of a button.

You can find the complete Chirp + TOTP integrated Demo iOS App
here

Coming up next is a tutorial to integrate your web application with the
receiver and authenticating your login. Watch this space!

Amogh Matt
amogh@chirp.io


Amogh is applying his MSc research in Sound and Music Computing to Chirp’s
digital signal processing tech stack, measuring performance metrics and
prototyping new techniques to improve performance.

Chirp is a technology company enabling a seamless transfer of digital
information via soundwaves, using a device’s loudspeaker and microphone only.
The transmission uses audible or inaudible ultrasound tones and takes place
with no network connection. To learn more visit chirp.io