Forum Discussion

JGodfrey's avatar
JGodfrey
New Contributor
11 years ago

WS Security UsernameToken– PasswordDigestExt and Base64

Hi all,

The password digest of the UsernameToken when using the SOAPUI PasswordDigestExt has an extra base64 encoding when compared to the OASIS standard.

See line 174 of the OASIS UsernameToken:
https://www.oasis-open.org/committees/d ... rofile.pdf
“Password_Digest = Base64 ( SHA-1 (nonce + created + password ) )”

Where as SOAPUI PasswordDigestExt is
Password_Digest = Base64 ( SHA-1 (nonce + created + Base64(SHA1(password)) )

See line 80:
https://github.com/SmartBear/soapui/blo ... Entry.java
“password = Base64.encode( sha.digest() );”

This means that Web Services that implement WS-Security as per the OASIS standard will error with SOAPUI version of the PasswordDigestExt as it’s not expecting the SHA1(password) to be Base64 encoded.

Regards,
John

7 Replies

  • gokussx4's avatar
    gokussx4
    New Contributor

    I ran across your post as I was in need of an older password digest algorithm when communicating with Amadeus Web Services (WBS). After diving through some articles on WSE and SoapUI I think this may just be a simple bug based on how I believe this was intended to be used.

     

    A SoapUi article describes PasswordDigestExt "The PasswordDigestExt option is non-standard and should only be used for interop issues where the message receiver desires an extra SHA-1 Hash of the password."

    https://www.soapui.org/soapui-projects/ws-security.html

     

  • gokussx4's avatar
    gokussx4
    New Contributor

    I ran across your post as I was in need of an older password digest algorithm when communicating with Amadeus Web Services (WBS). After diving through some articles on WSE and SoapUI I think this may just be a simple bug based on how I believe this was intended to be used.

     

    A SoapUI article describes PasswordDigestExt - "The PasswordDigestExt option is non-standard and should only be used for interop issues where the message receiver desires an extra SHA-1 Hash of the password."

    https://www.soapui.org/soapui-projects/ws-security.html

     

    The implementation under the covers does a Sha-1 encryption of the clear text password then does a base64 encoding to turn it into a string.

    UsernameEntry.java:

    if (PASSWORD_DIGEST_EXT.equals(passwordType)) {
                try {
                    MessageDigest sha = MessageDigest.getInstance("SHA-1");
                    sha.reset();
                    sha.update(password.getBytes("UTF-8"));
                    password = Base64.encode(sha.digest());
                } catch (Exception e) {
                    SoapUI.logError(e);
                }
            }

     

     

    Looking further into how the WSSecUsernameToken consumes that information to build xml I found this check for if the password is encoded then call a different overload that will decode the string back into the raw bytes that is the sha-1 of the clear text password:

    UsernameToken.java

    public void setPassword(String pwd) {
    if (pwd == null) {
    if (passwordType != null) {
    throw new IllegalArgumentException("pwd == null but a password is needed");
    } else {
    // Ignore setting the password.
    return;
    }
    }

    rawPassword = pwd; // enhancement by Alberto coletti
    Text node = getFirstNode(elementPassword);
    try {
    if (hashed) {
    if (passwordsAreEncoded) {
    node.setData(doPasswordDigest(getNonce(), getCreated(), Base64.decode(pwd)));
    } else {
    node.setData(doPasswordDigest(getNonce(), getCreated(), pwd));
    }
    } else {
    node.setData(pwd);
    }
    if (passwordType != null) {
    elementPassword.setAttributeNS(null, "Type", passwordType);
    }
    } catch (Exception e) {
    if (DO_DEBUG) {
    LOG.debug(e.getMessage(), e);
    }
    }
    }

     Since the WSSecUsernameToken extends WSSecBase, the setUserInfo method will only take a string typed password. That known, the authors did intend for the string password to possibly be encoded but their abstraction (instead of having an overload that accepts a byte[]), was to set a boolean of passwordsAreEncoded.

     

    I am going to create a pull request suggesting that this was a bug in the UsernameEntry.java code (but I am making a big assumption here on the intention) and that this would resolve the issue for those interoperating with an older password digest need.

     

    If I am correct the fix would be setting telling the UsernameToken that the password is encoded:

    if (PASSWORD_DIGEST_EXT.equals(passwordType)) {
    try {
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    sha.reset();
    sha.update(password.getBytes("UTF-8"));
    password = Base64.encode(sha.digest());
    token.setPasswordsAreEncoded(true);
    } catch (Exception e) {
    SoapUI.logError(e);
    }
    }

    I havfe al

  • gokussx4's avatar
    gokussx4
    New Contributor

    Terribly sorry about the multiple posts but when I went to Post it displayed no error and when I went to my email and found the link to verify it caused a number of posts to happen (probably because I refreshed the page that created the post). :(

    • nmrao's avatar
      nmrao
      Champion Level 3
      gokussx4,
      Sorry, could not go thru entire post. Do you have a question in there?
      • gokussx4's avatar
        gokussx4
        New Contributor

        No, I was replying to the OP and describing what I believe to be a bug in the code that defines the algorithm for password digest ext. I forked off of branch next and presented a pull request that fixes the problem.

         

        Here is the link to the pull request if you want to check it out:

        https://github.com/SmartBear/soapui/pull/265

         

        Again, I am sorry for the duplicate posts :)