OpenEdge中的WSSecurity,续

2024-06-25 23:25:52 发布

您现在位置:Python中文网/ 问答频道 /正文

作为这个问题的后续问题:Implementing WS-Security in Progress ABL,我将继续努力实现WS-Security-in-Progress-OpenEdge。在

我的问题:

每次请求特定的web服务时,我都会根据以下内容生成密码摘要:

  • “nonce”—一个随机字符串
  • 时间戳-当前时间
  • 密码-我和web服务提供商之间的共享机密。在

然后将nonce、timestamp和digest添加到web服务调用的Soap头中。在

这在大多数情况下都能正常工作,但在100个请求中有5个失败(请参阅下面的更多信息)。在

我就是这样生成摘要的:

PROCEDURE generatePassHashNonceClear:

/*------------------------------------------------------------------------------
  Purpose: 
    Generates a password hash for WS-Security

  General algorithm:
    Digest = base64(sha1(Nonce +  Timestamp + sha1(Pwd))) 
------------------------------------------------------------------------------*/
    DEFINE INPUT  PARAMETER pcNonce    AS CHARACTER   NO-UNDO.
    DEFINE INPUT  PARAMETER pcCreated  AS CHARACTER   NO-UNDO.
    DEFINE INPUT  PARAMETER pcPassword AS CHARACTER   NO-UNDO.

    DEFINE OUTPUT PARAMETER pcHash     AS CHARACTER   NO-UNDO.

    DEFINE VARIABLE mBytes        AS MEMPTR      NO-UNDO.
    DEFINE VARIABLE mSHA1         AS MEMPTR      NO-UNDO.

   /* 
    Set size of mempointer, add 20 since we are adding the 20 byte 
    SHA1-DIGEST of the clear password in the end.
    */
    SET-SIZE(mBytes) = LENGTH(pcNonce) + LENGTH(pcCreated) + 20.

    /* Put the decoded nonce first */
    PUT-STRING(mBytes, 1) = pcNonce.

    /* Add create time */
    PUT-STRING(mBytes, 1 + LENGTH(pcNonce)) = pcCreated.

    /* Set SHA1 returns a 20 byte raw string. */
    SET-SIZE(mSHA1) = 20.
    mSHA1 = SHA1-DIGEST(pcPassword).

    /* Add password, SHA1-digested (so we need to put bytes instead of a string */
    PUT-BYTES(mBytes, 1 + LENGTH(pcNonce) + LENGTH(pcCreated)) = mSHA1.

    /* Create out-data in B64-encoded format */
    pcHash = STRING(BASE64-ENCODE(SHA1-DIGEST(mBytes))).

    /* Clean up mempointers */
    SET-SIZE(mBytes) = 0.
    SET-SIZE(mSHA1)  = 0.

END PROCEDURE.

程序的名称如下:

^{pr2}$

我知道的:

这在10000个请求中的9500个请求中可以正常工作。但是有5%的失败率。不幸的是,错误消息没有帮助,所以我真正能看到的是登录失败。web服务提供程序声明由于不正确的摘要而拒绝登录。在

我做了什么:

为了测试我的摘要过程,我创建了一个小python程序。当我尝试使用失败登录的in数据(nonce和timestamp)时,确实会创建不同的摘要。不过,我不是Python程序员,所以这个程序很可能有问题(但它也应该在95%的情况下工作,这将是一个非常奇怪的巧合)。在

下面是python程序:

import hashlib

def createDigest(Nonce, Created, Password):
    "This function returns a digest"

    NonceB64 = Nonce.decode("base64","strict")

    pdgst = hashlib.sha1()
    pdgst.update(Password)
    PasswordDgst = pdgst.digest()


    FinalDgst = hashlib.sha1()
    FinalDgst.update(NonceB64)
    FinalDgst.update(Created)
    FinalDgst.update(PasswordDgst)

    FinalTxt = FinalDgst.digest().encode("base64","strict")
    print "Final digest : " + FinalTxt

    return

print "This digest is repeated in Progress OpenEdge"
createDigest("tGxF8+DAmJvQo93PNZt5Nw==", "2015-04-08T20:10:44:000Z", "SECRET")

print "This digest isn't repeated in Progress OpenEdge"
createDigest("XdcAW1TdTr+MLp4t0QkJ8g==", "2015-04-08T20:10:44:000Z", "SECRET")

我的真实密码当然不是“秘密”,这让我相信这个错误与现在有关。将密码更改为“SECRET”会使摘要有所不同,但Progress和Python摘要之间的差异仍然存在(上面的第一个示例在更改前后生成了类似的摘要,但第二个示例没有)。在

我有一个有进展支持的公开案件,但他们似乎和我一样在努力。在

我已经在OpenEdge 11.3.1和11.4中对RHEL和Windows7进行了测试,其行为保持不变。在


Tags: noin程序aslengthsha1progressdigest
1条回答
网友
1楼 · 发布于 2024-06-25 23:25:52

回答我自己的问题以备将来参考:

正如@TomBascom所指出的,这个问题与代码页转换有关,但实际的错误确实比SHA消化更早出现在“链”中。在

cNonceB64      = BASE64-ENCODE(GENERATE-RANDOM-KEY)
cNonce         = STRING(BASE64-DECODE(cNonceB64))

在第二行中,每当生成的密钥包含iso8859-1和UTF-8之间不匹配的值时,cNonce的值就会被销毁。在

简单的解决方案是将cNonce变量更改为mempointer,然后重写生成摘要的过程。在

^{pr2}$

然后是生成密码摘要的新过程:

PROCEDURE generateDigest:

/*                                       
  Purpose:     Generates a password hash for WS-Security
  Parameters:  <none>
  Notes:       
                                       */

    DEFINE INPUT  PARAMETER mNonce     AS MEMPTR      NO-UNDO.
    DEFINE INPUT  PARAMETER pcCreated  AS CHARACTER   NO-UNDO.
    DEFINE INPUT  PARAMETER pcPassword AS CHARACTER   NO-UNDO.

    DEFINE OUTPUT PARAMETER pcHash     AS CHARACTER   NO-UNDO.

    DEFINE VARIABLE mBytes        AS MEMPTR      NO-UNDO.
    DEFINE VARIABLE mSHA1         AS MEMPTR      NO-UNDO.

    /* 
    Set size of mempointer, add 20 since we are adding the 20 byte 
    SHA1-DIGEST of the clear password in the end.
    */
    SET-SIZE(mBytes) = LENGTH(pcCreated) + 36. /* 16 + 20 = 36 */

    /* Put the decoded nonce first */
    PUT-BYTES(mBytes, 1) = mNonce.

    /* Add create time */
    PUT-STRING(mBytes, 17) = pcCreated. /* 16 + 1 = 17 */

    /* Set SHA1 returns a 20 byte raw string. */
    SET-SIZE(mSHA1) = 20.
    mSHA1 = SHA1-DIGEST(pcPassword).

    /* Add password, SHA1-digested (so we need to put bytes instead of a string */
    PUT-BYTES(mBytes, 17 + LENGTH(pcCreated)) = mSHA1. /* 16 + 1 = 17 */

    /* Create out-data in B64-encoded format */
    pcHash = STRING(BASE64-ENCODE(SHA1-DIGEST(mBytes))).

    /* Clean up mempointers */
    SET-SIZE(mBytes) = 0.
    SET-SIZE(mSHA1)  = 0.
    SET-SIZE(mNonce) = 0.
END PROCEDURE.

相关问题 更多 >