简体   繁体   English

使用OpenSSL的Ruby中的编码和字节错误?

[英]Encoding and byte errors in Ruby using OpenSSL?

I was getting this error: 我收到此错误:

incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)

when trying to pass a variable from Rails to JavaScript via this line: 尝试通过以下行将变量从Rails传递给JavaScript时:

window.nonce = '<%= j @nonce %>';

My @nonce variable is an OpenSSL RSA public key encryption created by: 我的@nonce变量是由以下人员创建的OpenSSL RSA公钥加密:

@nonce = Rails.rsaEncUsingPublic(pubKey, randomStr)

def self.rsaEncUsingPublic(key, msg)
    return key.public_encrypt msg
end

I then tried adding force_encoding("UTF-8") to the end of the rsaEncUsingPublic function which changed the error to: 然后,我尝试将force_encoding("UTF-8")rsaEncUsingPublic函数的末尾,该函数将错误更改为:

invalid byte sequence in UTF-8

Now I clearly don't want to strip characters from an encrypted variable, however the same encryption function works fine everywhere else, until I'm passing it to JavaScript. 现在,我显然不想删除加密变量中的字符,但是在将其传递给JavaScript之前,相同的加密函数在其他地方都可以正常工作。

Printing out @nonce (with or without force encoding) does give a lot of gibberish: 打印出@nonce (使用或不使用强制编码)确实会带来很多@nonce

                                                            #??7:A}p[?ͼg/?%ŋ??=????h9?jg?    W?V?j ?}??G???t?7?i?:"???"#HM?0?L?????*r:ɦYaB&v&?5mǓŌ,???[U?Dt??G???Tև?&~??6f???????P??<GKV?`? p?K??B???????[?yj6?=?;?
 ???p?j=?Z?? ?[?5i??i?t?!???^?L{;??,??Ma\_mg?|??]A?????"??X:?򅡕?;???      ?y??\纘???#    ]?M" ?
          ?N

@nonce.encoding prints out UTF-8 . @nonce.encoding打印出UTF-8

@nonce.inspect pints out: @nonce.inspect指出:

"\u0015\xC0jn\xE7\xBC\xE4\u0016gV\x84&-ˌ+ŚA:4\xB1(\xC0\xEAv\x91\xE8>\u001D\x92ږ\xF6\xDC\xEE\x9A)\xC7&O\u001A\x90fเ\e\x9Bb*\xF2\xE2\u001E\xB9V\x9E\xBB\x9AUЕcU\u001E~\u0011\u0001$մ\xF8J\xED\xFE^\"\u001EC\xBD8\u0002\xBA\xDC\xDFIЊ, KU\u0000\u0014\u0015\x92_w\x95\x89\xD0-OfG\xB5\xF8LC\x9BO\\0j<ƥ\xA5\u001Dw(t?\xA4\xA2\u00174\xB5Š\xE3\x91s\xDA\u0002i\xB3\u0003Q\u000F\xF4\xDB5\x80\xD8\xE0./\x8B\x8A߳0\u0001\x91=$T\xCB\bLh\xF3\u001C\xFD\xBF\x95I%=gQ\u000F}\x8F_w\xFAn\x90\x81\xFC\b4\x9E\xC1\xD7y\xBC\xE8\xA4cQY\xB2@s1\xD7\xC9+\xA7\xEA>\xA5\xBC\xCF\xC81:TG\xFD\x88\xCCS\x90\xB1\x9Cv\xA3ݘ,\xA1;\xA5\xEE\xE4q9\u0000w\xB9\xB3\u0014\xD9\u0015\x8B\x82nw\ej\x82xkm)\x9Aa\xF1\xDD۬\xA2"

All help would be appreciated! 所有帮助将不胜感激!

So, the reason it is happening is within j method, exactly in this line: 因此,发生这种情况的原因正是在j方法中,恰好在此行中:

result = javascript.gsub(/(\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }

Note the lovely u at the end of the regex. 注意正则表达式末尾的可爱u This forced Ruby to fail the match if the given string is not UTF-8 compatible. 如果给定的字符串不兼容UTF-8,这将迫使Ruby失败。

Now, when you are encoding a string the result is not meant to be any form of human readable string - it is purely binary and no encoding will display anything useful. 现在,当您对字符串进行编码时,结果并不意味着是人类可读的字符串的任何形式-它纯粹是二进制的,没有任何编码会显示任何有用的信息。 Ruby, by default, is trying to display it with 'UTF-8', but this string is not 'UTF-8' compatible as it may contain non-UTF-8 sequences (since it may contain literally anything). 缺省情况下,Ruby尝试将其显示为'UTF-8',但此字符串不兼容'UTF-8',因为它可能包含非UTF-8序列(因为它可能包含任何文字)。

Now the solution won't be easy as this string is not a valid JavaScript string at all. 现在解决方案将变得不容易,因为此字符串根本不是有效的JavaScript字符串。 Also, even if you managed to convert it so that JavaScript, JavaScript might save the string representation differently, and the important thing is to keep the binary information unchanged. 另外,即使您设法将其转换为JavaScript,JavaScript可能也会以不同的方式保存字符串表示形式,并且重要的是保持二进制信息不变。 The easiest way is probably to convert the encrypted string into a number: 最简单的方法可能是将加密的字符串转换为数字:

window.nonce = '<%= @nonce.unpack('B*').first.to_i(2) %>';

It will result in a number which has a binary representation that is exactly the same as for the encrypted string. 它将产生一个数字,该数字具有与加密字符串完全相同的二进制表示形式。 You only need to be sure it is handled properly everywhere. 您只需要确保在任何地方都可以正确处理它。

Question: how is this string to be used in JavaScript? 问题:此字符串如何在JavaScript中使用?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM