Ruby - 肥皂和字节数组的摘要认证

Posted

技术标签:

【中文标题】Ruby - 肥皂和字节数组的摘要认证【英文标题】:Ruby - digest authentication for soap and byte arrays 【发布时间】:2012-03-27 10:17:44 【问题描述】:

如何将字符串或值转换为字节数组? 我需要它来进行 SOAP 身份验证。我的要求是—— 在客户端,这是创建摘要的方法: 1. 客户端摘要数组 = 字节数组 nonce + 字节数组 UTF-8 字符串的 UTC 日期时间 + 字节数组 UTF-8 纯文本密码(将这三者连接起来)。 2. 客户端 SHA-1 摘要 = 使用 SHA-1 算法的哈希客户端摘要数组。 3. 客户端 WS-Security Digest = 64 位编码客户端 SHA-1 摘要

Password_Digest = Base64 (SHA-1 (nonce + timestamp + password))

这是我用来生成随机数、时间戳和摘要密码的代码。用户密码是一个字符串。整个过程中出现了一些问题,我的摘要没有成功生成。我想我有这些数据类型是正确的,字节数组和 UTF8 让我感到困惑。 我添加了 utf8 转换但没有区别。

def nonce
   chars = ("a".."z").to_a + ("1".."9").to_a + ("A".."Z").to_a
   @nonce = Array.new(20, '').collectchars[rand(chars.size)].join
end

def timestamp
    t = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ")
    @timestamp = t.to_s
end

def digest_password

ic = Iconv.new('UTF-8//IGNORE', 'US-ASCII')
$time =  ic.iconv( timestamp + ' ')[0..-2]
$pass =  ic.iconv( password + ' ')[0..-2]
temp = (nonce.bytes.to_a + $time.bytes.to_a + $pass.bytes.to_a)
@digest_password = Base64.strict_encode64(Digest::SHA1.hexdigest(temp.to_s))

###  temp =  Digest::SHA1.hexdigest(nonce + timestamp + password) ##old    
###@digest_password = Base64.encode64(temp) ##old

end


    <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://xml.myserver.com/ok/service/v1_5" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Header>
       <wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
       <wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>user</wsse:Username>
       <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">YWIwM2QyZWI3YTEwMTAzZmNkNmZiNmEwMjg1ODlkOTU0OTNmNmUxYQ==
       </wsse:Password> 
       <wsse:Nonce>ZEUyQ2J6bmw5cjdDZmt1QjVqTjQ=</wsse:Nonce>
       <wsu:Created>2012-03-27T11:08:35.125Z</wsu:Created>
</wsse:UsernameToken>

【问题讨论】:

【参考方案1】:

终于可以解决这个问题了。

Password_Digest = Base64 ( SHA-1 ( nonce + create + password) )

nonce = nonce 作为字符串。在Base64 endoce之前,例如“1234”

create = 时间字符串。无编码

password = 密码字符串。没有编码。

Base64Nonce = Base64.encode64(nonce).strip #Base64 编码为“1234”

chars = ("a".."z").to_a + ("1".."9").to_a + ("A".."Z").to_a
nonce = Array.new(20, '').collectchars[rand(chars.size)].join

t = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ")

$time = t
$pass = p
Base64Nonce = Base64.encode64(nonce).strip 

$digest_pass = Base64.encode64(Digest::SHA1.digest(nonce + $time + $pass)).strip



          "wsse:Username" => username,
          "wsse:Password" => $digest_pass,
          "wsse:Nonce" => Base64Nonce,
          "wsu:Created" => $time,

【讨论】:

暂时有更简单的方法:require 'time'; Time.now.utc.iso8601(3)【参考方案2】:

nonce方法中Base64.encode然后在digest_password方法中再次Base64.encode是否正确?对我来说似乎很奇怪。也许你应该这样做

def nonce
   chars = ("a".."z").to_a + ("1".."9").to_a + ("A".."Z").to_a
   @nonce = Array.new(20, '').collectchars[rand(chars.size)].join
end

【讨论】:

Padde,已修复,但没有任何区别。

以上是关于Ruby - 肥皂和字节数组的摘要认证的主要内容,如果未能解决你的问题,请参考以下文章

什么是一维数组

在java中,如何清除每个方法中的字节[]数组以保护值免受内存转储?

JAVA IO流深入理解

在 Ruby 中使用 ("C") 指令打包成字节字符串

Delphi字节转换字节数组

java和c#的字节数组转换问题