Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

A256CBC_HS512 and AuthTag length #206

Closed
tommyseus opened this issue Nov 18, 2018 · 4 comments
Closed

A256CBC_HS512 and AuthTag length #206

tommyseus opened this issue Nov 18, 2018 · 4 comments
Assignees
Labels

Comments

@tommyseus
Copy link

Hello, i have a problem with the generated token and a php jwt lib.

package main

import (
	"fmt"
	"gopkg.in/square/go-jose.v2"
	"gopkg.in/square/go-jose.v2/jwt"
)

func main() {
	payload := struct {
		Test string
	}{
		Test: "Foo",
	}

	key := &jose.JSONWebKey{
		Key:       []byte("12345678901234567890123456789012"),
		Algorithm: "A256KW",
	}

	cl := jwt.Claims{}

	enc, err := jose.NewEncrypter(
		jose.A256CBC_HS512,
		jose.Recipient{
			Algorithm: jose.A256KW,
			Key:       key,
		},
		&jose.EncrypterOptions{
			Compression: jose.DEFLATE,
		},
	)
	if err != nil {
		panic(err)
	}

	raw, err := jwt.Encrypted(enc).Claims(cl).Claims(payload).CompactSerialize()
	if err != nil {
		panic(err)
	}

	fmt.Println(raw)
}

This code will create a raw string with a short auth tag (D2IoqyKAhOnv_5_mKB3PbQ):

eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiemlwIjoiREVGIn0.M8u6n3XY7w1m8RL9xlLPXS4z82IB-7zs1SvxHw605Qqy-Qz0dQhout4_O32jNRmHb11Y-r9RS_Bwgf17bGigmfYrjCHgEKqk.UUPxy7GF90ELGC9yi0eRSw.lIaZq3X3RRDctoWy5R7wVz7bfQhKx8w-Wrfb92aDfao5qAYNKMGHt8TBIdG6tZ3U.D2IoqyKAhOnv_5_mKB3PbQ

It is not possible to use this token with the following php script. The php code throws a exception (the exception is ignored) and the payload is empty.

Exception: InvalidArgumentException: Unable to verify the tag.

<?php

require __DIR__ . '/vendor/autoload.php';

$jwt = 'eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiemlwIjoiREVGIn0.M8u6n3XY7w1m8RL9xlLPXS4z82IB-7zs1SvxHw605Qqy-Qz0dQhout4_O32jNRmHb11Y-r9RS_Bwgf17bGigmfYrjCHgEKqk.UUPxy7GF90ELGC9yi0eRSw.lIaZq3X3RRDctoWy5R7wVz7bfQhKx8w-Wrfb92aDfao5qAYNKMGHt8TBIdG6tZ3U.D2IoqyKAhOnv_5_mKB3PbQ';

$jwk = \Jose\Component\Core\JWK::create(
    [
        'kty' => 'oct',
        'k' => \Base64Url\Base64Url::encode('12345678901234567890123456789012'),
        'alg' => 'A256KW',
    ]
);

$jweSerializerManager = \Jose\Component\Encryption\Serializer\JWESerializerManager::create([
    new \Jose\Component\Encryption\Serializer\CompactSerializer(new \Jose\Component\Core\Converter\StandardConverter()),
]);

$algorithmManager = \Jose\Component\Core\AlgorithmManager::create([
    new \Jose\Component\Encryption\Algorithm\KeyEncryption\A256KW(),
]);

$contentEncryptionAlgorithmManager = \Jose\Component\Core\AlgorithmManager::create([
    new \Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512(),
]);

// The compression method manager with the DEF (Deflate) method.
$compressionMethodManager = \Jose\Component\Encryption\Compression\CompressionMethodManager::create([
    new \Jose\Component\Encryption\Compression\Deflate(),
]);

$jweDecrypter = new \Jose\Component\Encryption\JWEDecrypter(
    $algorithmManager,
    $contentEncryptionAlgorithmManager,
    $compressionMethodManager
);

$jwe = $jweSerializerManager->unserialize($jwt);

$jweDecrypter->decryptUsingKey($jwe, $jwk, 0);

var_dump($jwe->getPayload());

I think the problem is auth tag is to short. If i change the harcoded authtagBytes to the keysize value (32) then everythink works.

go-jose/symmetric.go

Lines 103 to 111 in 9ab2713

func newAESCBC(keySize int) contentCipher {
return &aeadContentCipher{
keyBytes: keySize * 2,
authtagBytes: 16,
getAead: func(key []byte) (cipher.AEAD, error) {
return josecipher.NewCBCHMAC(key, aes.NewCipher)
},
}
}

func newAESCBC(keySize int) contentCipher {
	return &aeadContentCipher{
		keyBytes:     keySize * 2,
		authtagBytes: keySize,
		getAead: func(key []byte) (cipher.AEAD, error) {
			return josecipher.NewCBCHMAC(key, aes.NewCipher)
		},
	}
}

Would be nice if someone could check the value for authtagBytes.

@csstaub
Copy link
Collaborator

csstaub commented Nov 20, 2018

Hi @tommyseus, that's looks like a bug indeed! According to RFC 7518 Section 5.2.5 the auth tag length should indeed be the key size. I can make a quick pull request to fix this.

csstaub added a commit that referenced this issue Nov 20, 2018
The auth tag len for AES-CBC+HMAC algorithms should match the key size,
see RFC 7518 Section 5.2.4 and Section 5.2.5. Unfortunately this will
(as-is) cause problems with decrypting AES-CBC+HMAC ciphertexts that
were encrypted with this library that used 192-bit and 256-bit key
sizes. A future pull request could add a flag to add some sort of
compabitility flag to allow for decryption to continue working for those
cases.
@csstaub
Copy link
Collaborator

csstaub commented Nov 20, 2018

See: #207

@csstaub
Copy link
Collaborator

csstaub commented Nov 20, 2018

The pull request above will fix the issue, but in the meantime I would recommend using AES-128-GCM (or AES-128-CBC-HMAC) as a cipher. GCM is superior to CBC+HMAC, and a 128-bit key is sufficient for all practical use-cases.

@csstaub csstaub self-assigned this Nov 20, 2018
@csstaub csstaub added the bug label Nov 20, 2018
csstaub added a commit that referenced this issue Nov 30, 2018
@csstaub
Copy link
Collaborator

csstaub commented Nov 30, 2018

Fix is in 2.2.0, please reopen if you continue to experience issues @tommyseus.

@csstaub csstaub closed this as completed Nov 30, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants