Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

HMAC (SHA1) key longer than 81 characters not possible?

UweFetzer_se38
Active Contributor
0 Kudos

Not sure whether I'm in the correct forum...

To sign a message for a specific application with HMAC-SHA1 hash I need a 83 character key.

My problem: the function module 'SET_HMAC_KEY' throws the exception "param_length_error". After I've testet with several key length, I found out, that the maximum valid length is 81. Is there any reason for this?

With 3rd party libraries (ie. Python and Javascript) longer keys are working.

Code:

 
CALL FUNCTION 'SET_HMAC_KEY'
  EXPORTING
    generate_random_key         = ' '
    alg                         = 'SHA1'
    keycstr                     = 'cB1phTHISISATESTVuZMDmWCz1CEMy82iBC3HgFLpE&7857T...YFqV93gRJQ'
    client_independent          = ' '
  EXCEPTIONS
    unknown_alg                 = 1
    param_length_error          = 2
    internal_error              = 3
    param_missing               = 4
    malloc_error                = 5
    abap_caller_error           = 6
    base64_error                = 7
    calc_hmac_error             = 8
    rsec_record_access_denied   = 9
    rsec_secstore_access_denied = 10
    rsec_error                  = 11
    rng_error                   = 12
    record_number_error         = 13
    OTHERS                      = 14.

Best regards, Uwe

Edited by: Julius Bussche on Aug 5, 2010 10:19 PM

I truncated the key further because in a coding tag it toasts the formatting when too long.

1 ACCEPTED SOLUTION

martin_voros
Active Contributor
0 Kudos

Hi,

that number 81 seems completly random to me. 81 characters (bytes) is 648 bits. Here is a quote from [RFC 2104 - HMAC: Keyed-Hashing for Message Authentication|http://www.faqs.org/rfcs/rfc2104.html].

The key for HMAC can be of any length (keys longer than B bytes are

first hashed using H). However, less than L bytes is strongly

discouraged as it would decrease the security strength of the

function. Keys longer than L bytes are acceptable but the extra

length would not significantly increase the function strength. (A

longer key may be advisable if the randomness of the key is

considered weak.)

So there is no limit for key size but any key longer than block size (B bytes) of hash function will be compressed to B bytes. The key should be longer than output size of has function (L bytes) which for SHA-1 is 160 bits = 20 bytes. The internal state of SHA-1 is 512bits == 64 bytes.

So I would suggest that to use SHA-1 functin to reduce any key longer than 64 bytes to 64 bytes and then to pass a new key to SET_HMAC_KEY.

Cheers

14 REPLIES 14

Former Member
0 Kudos

I dont know if all would agree on this:

This seems to be a development question.

0 Kudos

Hi Franklin,

Forum description:

...secure collaboration, such as message security (encryption) and trust management...

Regards, Uwe

0 Kudos

I have no clue on this topic , we will wait for some experts to answer.

tim_alsop
Active Contributor
0 Kudos

I'm not sure if this helps, but if you look at http://en.wikipedia.org/wiki/HMAC you will see following text:

The size of the output of HMAC is the same as that of the underlying hash function (128 or 160 bits in the case of MD5 or SHA-1, respectively),

Of course, this doesn't mean that any library included with SAP product, or added as a third-party crypto library will support the full 160-bits (20 bytes)

Also, I think you will find that the encryption alg used with HMAC-SHA1 will determine the key length, not the hash alg.

Thanks,

Tim

0 Kudos

Hi Tim,

that's what makes me astonished. Not the encryption FM 'CALCULATE_HMAC_FOR_CHAR' I'm using later in my app is the problem, but the simple setter method 'SET_HMAC_KEY'.

Uwe

tim_alsop
Active Contributor
0 Kudos

If you look at the wikipedia page I referenced earlier, you will see it shows:

function hmac (key, message)
    if (length(key) > blocksize) then
        key = hash(key) // keys longer than blocksize are shortened
    end if
    if (length(key) < blocksize) then
        key = key u2225 zeroes(blocksize - length(key)) // keys shorter than blocksize are zero-padded
    end if

So, you just need to know what the blocksize is and then you will know what max key size can be input into hmac alg. If the key used is larger it will be shortened, and if shorter it will be zero padded to make it same as blocksize.

I think for sha-1 the block size is 64, so this should be the max key length for hmac. I found a useful explanation at http://stackoverflow.com/questions/3341167/how-to-implement-hmac-sha1-algorithm-in-qt

Thanks,

Tim

Former Member
0 Kudos

Note that the functions are not released and encapsulate a kernel-function to write the key into the SecureStorage area - there will be no publicly available information on these as far as I am aware and are insecure to use (from a stability perspective).

What is publicly known about the SecureStorage area is that the call-stacks are protected to access the data again (particularly to decrypt) so I can't see how this would work in your own application because even within SAP only special programs are allowed to call the functions.

What data is the application trying to store? A password? Possibly there is a better way to deal with it in a secure manner.

Have you looked into the SSF (Secure Store & Forward) because you mentioned "signing a message"?

Cheers,

Julius

Edited by: Julius Bussche on Aug 5, 2010 10:21 PM

0 Kudos

Hi Julius,

I'm using 'CALCULATE_HMAC_FOR_CHAR' to sign messages (OAuth) and it works great until the encryption key is less than 82 chars.

Since the documentation for the function group SECH is rolled out in 7.01 sp07 (note 1416202) I thought the usage of these function mudules is secure (lol) and allowed.

Regards, Uwe

Former Member
0 Kudos

Ahh.. I'm on 7.01 SP 6...

Thanks for the info though!

I will ping someone for you to take a look into this import parameter option. Is it not mentioned in the documentation?

Cheers,

Julius

0 Kudos

I'm on 7.01 SP 6

me too

But you can find the docu here: (German only)

Parameter length limits are not mentioned.

(Danke für Deine Bemühungen)

Uwe

martin_voros
Active Contributor
0 Kudos

Hi,

that number 81 seems completly random to me. 81 characters (bytes) is 648 bits. Here is a quote from [RFC 2104 - HMAC: Keyed-Hashing for Message Authentication|http://www.faqs.org/rfcs/rfc2104.html].

The key for HMAC can be of any length (keys longer than B bytes are

first hashed using H). However, less than L bytes is strongly

discouraged as it would decrease the security strength of the

function. Keys longer than L bytes are acceptable but the extra

length would not significantly increase the function strength. (A

longer key may be advisable if the randomness of the key is

considered weak.)

So there is no limit for key size but any key longer than block size (B bytes) of hash function will be compressed to B bytes. The key should be longer than output size of has function (L bytes) which for SHA-1 is 160 bits = 20 bytes. The internal state of SHA-1 is 512bits == 64 bytes.

So I would suggest that to use SHA-1 functin to reduce any key longer than 64 bytes to 64 bytes and then to pass a new key to SET_HMAC_KEY.

Cheers

0 Kudos

Hi Martin,

So I would suggest that to use SHA-1 functin to reduce any key longer than 64 bytes to 64 bytes and then to pass a new key to SET_HMAC_KEY.

Unfortunatelly I cannot cut the key.

The definition of the [HMAC-SHA1 OAuth key|http://tools.ietf.org/html/rfc5849#page-25] according RFC 5849:

key is set to the concatenated values of:

1. The client shared-secret, after being encoded

(Section 3.6).

2. An "&" character (ASCII code 38), which MUST be included

even when either secret is empty.

3. The token shared-secret, after being encoded

(Section 3.6).

And the result in my case is a string of 83 characters.

Regards, Uwe

0 Kudos

Hi,

yes, we can :-). Let say that SAP implementation supports a key with size more than 81 bytes. Then according to specification if the key is longer than block size of hash function (64 bytes for SHA-1) then it would use hash function to reduce original key to new key with size equals to output size of hash function (20 bytes for SHA-1). Therefore doing this step manually before calling SET_HMAC_KEY is equal to calling SET_HMAC_KEY which supports keys longer than 81 bytes.

The easiest way how to check this is to compare some HMAC-SHA1 implementation with the result produced by my proposed logic.


DATA: text TYPE string,
        key_str TYPE string,
        hash TYPE hash160x,
        key TYPE xstring,
        hmac TYPE hash512_base_64.

  text = 'Hello'.
  key_str = '012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'.

  CALL FUNCTION 'CALCULATE_HASH_FOR_CHAR'
    EXPORTING
      data  = key_str
    IMPORTING
      hashx = hash.
  key = hash.

  CALL FUNCTION 'SET_HMAC_KEY'
    EXPORTING
      generate_random_key = space
      alg                 = 'SHA1'
      keyxstr             = key
      client_independent  = space.

  CALL FUNCTION 'CALCULATE_HMAC_FOR_CHAR'
    EXPORTING
      alg        = 'SHA1'
      data       = text
    IMPORTING
      hmacbase64 = hmac.

  WRITE: / hmac.

Javascript version


var hmac = Crypto.HMAC(Crypto.SHA1, "Message", "Secret Passphrase");

var hmacBytes = Crypto.HMAC(Crypto.SHA1, "Message", "Secret Passphrase", { asBytes: true });
var hmacString = Crypto.HMAC(Crypto.SHA1, "Message", "Secret Passphrase", { asString: true });

Both implementations return "qsXNz/wecK4PMob6VG9RyRX6DQI=".

Cheers

Sorry for formatting but it looks like something is broken.

Edited by: Martin Voros on Aug 6, 2010 10:34 PM

0 Kudos

Martin, BIIIINGO -> that's it!!!

Great, thank you very much, you saved my day.

Take a beer on my bill

Uwe