See latest blog post on this.
Having worked out what the WSSE PasswordDigest uses, I am struggling to get past "Authorization Failure.", and sadly it sounds like they have all buggered off home.
The example they sent me matched what I worked out, it includes a Nonce, and a Created date time, and using the password supplied, I was able to create the same Password digest.
To do this I had to use a Password in the algorithm that was not the actual password.
Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
I had to use a base64(sha1(password)) in its place. That worked to match the example. But it is not letting me log in. I used this because the specification says "For Shipping API V2 the password used in
the below formula is the base 64 encoding of the SHA-1 hash of the plain text password." even though it goes on to say "Password_Digest = Base64(SHA-1(Nonce + Created + SHA-1(Password)))"
However, I have found the spec has errors, little things like it defines an object unitofMeasure which if used causes the whole fail to report "schema validation failure". The example had unitOfMeasure which works. So I cannot actually trust the spec. Not a good start.
However, they helpfully provide a zip of various versions of the authentication done in different languages. This is useful, but also shows that something that should be simple is in fact clearly very complicated.
In perl they provide :-
my $conct = $nonce . $creationdate . (sha1($password));
my $passworddigest = encode_base64(sha1($conct));
Which seems to use simply the raw SHA-1 of the password in the algorithm, not a base64 of it.
In PHP they provide :-
$nonce_date_pwd = pack("A*",$nonce) . pack("A*",$CREATIONDATE) . pack("H*",sha1($password));
$PASSWORDDIGEST = base64_encode(pack('H*', sha1($nonce_date_pwd)));
Now, my PHP is not good, but reading up, the H* means hex encoded. So that looks like it uses a hex coding of the SHA-1 of the password in the algorithm, not a base64 coded version.
In python :-
hashedpassword = sha.new(password).digest()
digest = sha.new(nonce + CREATIONDATE + hashedpassword).digest()
PASSWORDDIGEST = base64.b64encode(digest)
Which looks like using the raw SHA-1 in the algorithm, not a base64 coded.
So I am thinking the spec, and the example they gave me, is wrong. I even tried using their python code to generate Created, Nonce, and Password fields.
Sadly, it is not working to get past "Authorization Failure.", and it looks like the have buggered off home.
This is NOT THE WAY to specify an API. You need clear documentation that is actually correct, and you need helpful error messages on your on-ramp system. Not impressed at all.
Update: Nope, they are there until 6pm - yay, well done Royal Mail - trying to find the problem for me now.
Update: We are back to the base64(SHA-1(plaintextpassword)) now, and using a different applicationId, and working. Yes, that disagrees with all of their code samples! So hoping to get on live system soon.