Like it or not SMS two factor authentication is prevalent in the market today. Most, if not all, of the major shopping, social media, financial and system maintenance sites rely on SMS two factor authentication to verify when users log in. Amazon, Twitter, Facebook, Google, banks, stock traders, cryptocurrency sites, government servers and many others utilize the method of sending a one-time pass code key via SMS text to the listed user cell phone number to validate a user. The user enters this pass code to complete the transaction or log into the site.

However, the current state of SMS two factor authentication is risky and filled with holes. SMS-transmitted pass codes are susceptible to a variety of attacks. For example, hackers have obtained control of a target’s cell phone number by calling the cellular provider or going into a retail store of the provider and impersonating the subscriber. This attack is known as SIM swapping or SIM hijacking. In fact, the chief technology officer of the US Federal Trade Commission had her number hijacked by this method in 2016.

Another common attack is for hackers to exploit the fundamental weaknesses in the SS7 routing protocol used by cellular carriers around the world to intercept text messages and the associated phone number. Another attack was simply poor security on the back end. A Berlin-based security researcher recently discovered vulnerability in a server database belonging to Voxox, exposing tens of millions of copies of personally identifying information including SMS messages; password reset links, and two-factor authentication codes.

By hijacking the target's phone number, hackers are able to seize control of banking, financial, retail, social media accounts. Thus, when a site sends a one-time pass code to the user - the pass code goes to the phone now under hacker control. In one recent example, Reddit, an American social news and discussion website, had its internal software maintenance team impersonated by hackers who obtained the two factor pass codes.

“Already having our primary access points for code and infrastructure behind strong authentication requiring two-factor authentication (2fa), we learned that SMS-based authentication is not nearly as secure as we would hope, and the main attack was via SMS intercept,” a Reddit officials wrote in response to the attack.

While some companies tried to make the transition to hardware generated token keys - the additional expense is difficult to justify and often inventory control of hardware in the field becomes nearly impossible. The final solution is to secure the current means of SMS one time pass codes utilizing encryption. If users are able to encrypt the one time pass code, many of the problems encountered by sim jacking, SS7 weakness and SMS interception, are solved with little or no cost.

Some researchers and writers have suggested that SMS cannot be secured nor is it capable of being encrypted. SMS was designed in an era when security was not an issue and it was intended to transmit short text messages. However, the assertion that it cannot be encrypted is incorrect.

It is clear that a secure SMS software app is rarely if ever provided by hardware makers or cellular providers as the default on cell phones today. There are a variety of reasons for this lack of capability. One big problem is inter-operability between devices on different networks and manufacturers. In short, messages sent using encryption are usually in a unique format to the specific hardware and software.

What is needed is an Encrypted Short Universal Message (ESUM) protocol which can be used by all developers to establish a joint communications method to link with all users on a common basis. The ESUM can be used by cell phone message providers to finally beef up the security of the SMS service so subscribers can enjoy private communications. The ESUM can also be used by back end providers on the server networks such as the current targets of cyber-crime to authenticate subscribers and employees who need access via the one time pass code two factor system.

The ESUM protocol can be adopted for Two Factor Authentication by assigning or allowing the user to generate a pass phrase at the initial account set up much like the standard log on password industry standard. The ESUM passphrase would be entered onto their cell phone by the user when they initiate the Two Factor Authentication.

For most situations this would be when the user elects to use ESUM for authentication. However, in the case of corporate assignments, the ESUM set up would be initiated by the local IT technical support acting under the Information Security Officer (CISO) authority.

The front end app developer is responsible to the ESUM security while it is at rest on the cell phone. The developer of the cell phone SMS app is required to secure the ESUM passphrase locally on the cell phone to prevent unauthorized access unless the user is logged in via the app itself. The SMS app should also be able to recognize that it is receiving an inbound ESUM message from a particular source, and then decode/display the message for the user based on the passphrase.

The back end developer is responsible for the ESUM security while it is at rest on the server. The developer of the server software must prevent unauthorized access while enabling the server software to generate a random one-time pass code during a user log in, encrypt the one time pass code in the ESUM protocol with the passphrase and then transmit it to the user via SMS.

Since SMS is based on the user phone number assigned by the cellular provider, the identification can be based on the initial set up of the ESUM combined with the phone number. If the phone number has been hijacked or if the SMS is intercepted, the ESUM is sent to the attacker who does not have access to the decode pass phrase. Thus, the hacker will be unable to decode the one time passcode in order to log in.

In an effort to spur the introduction of a more secure two factor SMS it is proposed to establish an ESUM format. This ESUM protocol is based on AES 256 bit encryption using either an assigned or user selected pass-phrases up to 200 characters in length. The current state of secure random password assignment is between 12 and 16 characters in length with accompanying best estimates that to crack them will take decades. Clearly, allowing for up to 200 characters greatly increases this level of security.

The ESUM format protocol is broken up into three main segments: the random seed, the multiple-message header, and the message body.

The multiple-message header is required because cellular SMS is limited to 140 characters total for transmission. This 140 character limit can quickly be exceeded by encrypted messages which require extra overhead for security. After the header and the extra length of encrypting the actual message itself - it is best to break an un-encoded text into slices of 50 character blocks and then recombine them using the software. Thus one can send readable text to the user that exceeds the 140 character limit while remaining within the bounds of the cellular SMS transmission limitations.

For example, in base zero, if you had an original un-encoded text of 200 characters it would break into four parts with the header block reading as follows:

30 - Four messages total with this message being the first 50 characters
31 - Four messages total with this message being the second 50 characters
32 - Four messages total with this message being the third 50 characters
33 - Four messages total with this message being the (last) fourth 50 characters

It is worth noting that due to the means by which SMS messages are sent and delivered that it is possible for the cellular provider to send the messages out of order. The app developer should take this into account and provide a sorted means of re-assembling the original text for the user.

The format of the ESUM message is a simple ten character random number to seed the pass phrase, two characters for multiple-message header in base zero (e.g. 0 of 3, 1 of 3, 2 of 3, 3 of 3), and a message body of base 64 text with the first 16 bytes being the IV value for the AES encryption. The ESUM passphrase serves as the AES key by being combined with the ten character random number seed and then hashed using SHA 256.

AES encryption requires a random seed, an IV value and a key. Each message may share the same key but the IV and seed values need to change with each message. The seed and IV values can be sent with the message.

For example the following encrypted message:


Is broken down into these components:

Is the 10 character random seed value

Is the multiple-message header in zero base total number of messages being one (e.g. 0 in zero base) and this is message one of one (0 in zero base).

Is the message block in base 64 with the first 16 bytes being the IV value for the AES CBC encryption.




// set up 10 character seed header
// use secure random generation
SecureRandom rand = new SecureRandom();
int xseed=rand.nextInt(99999);
String the_seed=String.valueOf(xseed);
//first five bytes done - do second five bytes
String Seed_header = String.valueOf(xseed);
Seed_header = "00000".substring(Seed_header.length()) + Seed_header;
//Seed_header for frist 10 characters in message format
//add Seed_header to passpharase key and sha 256 hash
MessageDigest md;
String aes256 = "";
try {
md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest();
aes256 = new String(digest, "ISO-8859-1");
} catch (NoSuchAlgorithmException e2) {
// TODO Auto-generated catch block
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
String keyString = aes256.substring(0, 32);
//set up iv
byte[] iv = new byte[16];
String ivString = new String(iv, "ISO-8859-1");
byte[] inputBytes = msg_input.getBytes("ASCII");
// text message is in msg_input
byte[] keyBytes = keyString.getBytes("ASCII");
//set up AES 256 CBC
AESEngine engine = new AESEngine();
CBCBlockCipher blockCipher = new CBCBlockCipher(engine);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher);
//Default scheme is PKCS5/PKCS7
//place the key and iv in the AES engine
KeyParameter keyParam = new KeyParameter(keyBytes);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 16);
// Encrypt
cipher.init(true, keyParamWithIV);
byte[] outputBytes = new byte[cipher.getOutputSize(inputBytes.length)];
int leng = cipher.processBytes(inputBytes, 0, inputBytes.length, outputBytes, 0);
cipher.doFinal(outputBytes, leng);
//Do the final block
// add the iv 16 bytes in front of the message output block
byte[] c = new byte[iv.length + outputBytes.length];
System.arraycopy(iv, 0, c, 0, iv.length);
System.arraycopy(outputBytes, 0, c, iv.length, outputBytes.length);
// convert work byte array C to base 64 text
String base64 = Base64.encodeToString(c, Base64.DEFAULT);
String msg_output = base64;