Chirp + TOTP (Generation and Transmission)

Amogh Matt
Chirp
Published in
6 min readJul 26, 2018

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.

Replay Attack

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.

Step 1

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.

Step 2

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.

Step 3

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 also 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 the Chirp iOS examples 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

--

--