iT邦幫忙

1

如何跨網域抓取加密JSON

esel 2019-02-18 11:15:423737 瀏覽

各位大大好,
我想要跨網域到 https://www.surveycake.com/webhook/v0/8aa7P/d8cc4036f4250ab5fb20e02eba994458 抓取加密的JSON內的資訊。

是用AES-128-CBC方式加密。
Hash key:9ecd1c41431e6624
IV key:83ca97ad7a04c92b
想使用ASP+script來處理。

我嘗試過用getJSON() 等方法都抓不到值,想請各位指教整個流程大概方向,不好意思太麻煩大家,只希望提供大概要用哪些指令可以完成整個流程。

esel iT邦新手 4 級 ‧ 2019-02-18 13:34:05 檢舉
先謝謝各位回答的方案,初學的我可能要消化一下~~感謝大家!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
4
淺水員
iT邦大師 6 級 ‧ 2019-02-18 11:27:33
最佳解答

目前問題是抓不到資料,跟加密應該無關。
如果對方伺服器沒有送 「Access-Control-Allow-Origin」的檔頭
那就不能透過 AJAX 抓到值
這時候必須由自己的伺服器處理
用 ASP 抓對方伺服器的資料再送給使用者
(而不是 使用者瀏覽器透過 javascript 抓)

PS. ASP我不熟,稍微查一下好像可以用 WinHttpRequest 取得其他伺服器的資料。

更新:
我錯了,看到「我嘗試過用getJSON() 等方法都抓不到值」這句話就認為是沒抓到資料的問題。
實際上該連結確實如 藍諾 所言有加上「Access-Control-Allow-Origin:*」檔頭了
但是因為尚未解密,所以不能用 getGetJson 收資料
改用一般的接收文字資料的方式即可,收完再解密。
下面是前端處理的方式,但請參考 藍諾 的解答,有提到安全性的問題,所以最好還是在後端處理。

$(function(){
    $.ajax({
        url:'https://www.surveycake.com/webhook/v0/8aa7P/d8cc4036f4250ab5fb20e02eba994458',
        method:'GET',
        //因為有 Content-Type:application/json; charset=utf-8 檔頭
        //所以要直接指定 dataType:'text'
        //避免 jquery 自動用json方式解析
        dataType:'text',
        success:onAjaxSuccess,
        error:onAjaxError
    });
});

function onAjaxSuccess(data)
{
    const iv='83ca97ad7a04c92b',
          key='9ecd1c41431e6624';
    const decrypted = CryptoJS.AES.decrypt(
        CryptoJS.lib.CipherParams.create({
            ciphertext: CryptoJS.enc.Base64.parse(data)
        }),
        CryptoJS.enc.Utf8.parse(key),
        {
            iv: CryptoJS.enc.Utf8.parse(iv)
        }
    );
    const json = JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
    console.log(json);
}

function onAjaxError(xhr)
{
    console.log('error');
}
esel iT邦新手 4 級 ‧ 2019-02-19 10:15:29 檢舉

感謝~如果要後端處理要往哪方向著手?

淺水員 iT邦大師 6 級 ‧ 2019-02-19 13:54:32 檢舉

我完全沒寫過 ASP 呢,也不知道你那邊是不是 .NET 的
目前我只能說明上面例子中的運作原理

首先要知道 AES 加密的操作都是二進位資料操作
所以要先想好今天怎麼樣把字串轉為二進位序列
(通常函式庫可能會以 byte array 或是自己定義的容器來儲存此二進位序列)

上面程式碼中 CryptoJS.enc.Utf8.parse 功能就是以 utf8 編碼的方式把 key 跟 iv 這兩個字串分別轉為二進位序列。而 data 則是以 CryptoJS.enc.Base64.parse 轉為二進位序列。所以會有三個二進位序列:keyivdata

都轉成二進位序列後,才能用 AES 函式去做解密,會得出一個解密後的二進位序列。最後還要把這個二進位序列轉換成字串,這裡是透過 [CryptoJS二進位序列容器].toString(CryptoJS.enc.Utf8) 來轉換,其中 CryptoJS.enc.Utf8 是指定用 utf8 的編碼讀取出來。

上面有個東西我忘記說,除了 keyivdata 之外,還要選擇一個 padding的方法,但 CryptoJS 有預設用 pkcs7-apdding 作為 padding 的方法了,所以沒額外指定。

簡而言之,AES需要的參數有:keyivdatapadding
前三個都會轉為二進位序列,而 padding 則是一個 method

esel iT邦新手 4 級 ‧ 2019-02-21 09:28:37 檢舉

感謝~我測試成功了!

0
小魚
iT邦大師 1 級 ‧ 2019-02-18 11:39:03

一般來說,
前端的Ajax不能抓跨網域的資料,
這應該是JavaScript的安全限制,
最近在寫PHP的API也是遇到這個問題,
需要後端程式允許跨網域才能夠解決.

2
藍諾
iT邦新手 5 級 ‧ 2019-02-18 13:20:04

你提供的網址是公開 API,可使用純 JS 達成訪問,Demo:

https://jsfiddle.net/nzfhguo2/2/

結果:
https://ithelp.ithome.com.tw/upload/images/20190218/20111944qJnjQzhUIJ.png

備註:以上可能並非最佳解,只是快速回答你一個參考方向。
注意:不建議在公開環境透過 JS 取得,因為你的 Hash/IV 等於變相公開,除非沒有敏感資料考量或該 JS 為私人使用,請自行斟酌。

參考來源:

https://github.com/SurveyCake/webhook#step-4-%E8%A7%A3%E5%AF%86%E7%AD%94%E6%A1%88

淺水員 iT邦大師 6 級 ‧ 2019-02-18 19:56:44 檢舉

我發現 github 的說明有寫錯
他們其實用的是 AES-128-CBC (PKCS7-padding)
而不是 zero-padding

esel iT邦新手 4 級 ‧ 2019-02-19 10:17:01 檢舉

感謝藍諾大提供協助,但實在很笨在console.log 都看的到,就是無法把資料轉出來。

藍諾 iT邦新手 5 級 ‧ 2019-02-20 10:18:00 檢舉

不太清楚你說得無法把資料轉出來的意思,

請看以下示範是否有解決你的問題?

https://jsfiddle.net/pzq58mfb/2/

0

正常來講,因為安全性的問題,大多數來說是不能用ajax來直接取得其它域名的頁面資料。
除非是對方有開通Access-Control-Allow-Origin。

但在你直接打入網址就可以獲得資料的情況下。是可以轉由後端程式來幫你取得內容。
一般來說curl就是其中一種方式。當然也可以使用一些能取遠端內容的函數來幫忙也是可以的。
(不過aspnet我不熟,所以這部份就自行查看有什麼函數可以用了)

esel iT邦新手 4 級 ‧ 2019-02-19 09:21:35 檢舉

感謝~我研究看看

我要發表回答

立即登入回答