【问题标题】:secure http call in androidandroid中的安全http调用
【发布时间】:2013-04-08 12:23:13
【问题描述】:

如何在每次从我的应用程序触发时确保 http 调用的安全,并且它还需要超时,以便任何其他用户无法从任何浏览器使用相同的链接。

我特别在寻找 android 解决方案,而不是 html 表单。

请帮帮我。 无法解决此问题,也不知道该往哪个方向进行。

提前致谢。

我附上了 PHP 和 Android 的代码,它们发布请求并返回响应,但没有附加安全性,任何用户都可以通过随时从浏览器调用相同的 HTTP 响应来获得相同的响应...

安卓代码:

public class CustomizedListView extends Activity {
    // All static variables
    static final String URL = "http://example.com/getmsgs/strno=123";
    // XML node keys
    static final String KEY_SONG = "song"; // parent node
    static final String KEY_ID = "id";
    static final String KEY_TITLE = "title";
    static final String KEY_ARTIST = "artist";
    static final String KEY_DURATION = "duration";
    static final String KEY_THUMB_URL = "thumb_url";

    ListView list;
    LazyAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

        JSONObject json = JSONfunctions.getJSONfromURL(URL);


        try {
            JSONObject arr2 = json.getJSONObject("feed");
            JSONArray arr = arr2.getJSONArray("entry");

            for (int i = 0; i < arr.length(); i++) {
                JSONObject e1 = arr.getJSONObject(i);

                JSONArray arr3 = e1.getJSONArray("im:image");

                JSONObject arr8 = e1.getJSONObject("im:name");

                JSONObject arr10 = e1.getJSONObject("im:artist");

                    JSONObject e12 = arr3.getJSONObject(0);

            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();

            map.put(KEY_THUMB_URL,  e12.getString("label"));

            map.put(KEY_ARTIST, arr8.getString("label"));
            map.put(KEY_TITLE, arr10.getString("label"));
            // adding HashList to ArrayList
            songsList.add(map);
            }

        } catch (JSONException e) {
            // Log.e("log_tag", "Error parsing data "+e.toString());
            Toast.makeText(getBaseContext(),
                    "Network communication error!", 5).show();
        }


        list=(ListView)findViewById(R.id.list);

        // Getting adapter by passing xml data ArrayList
        adapter=new LazyAdapter(this, songsList);        
        list.setAdapter(adapter);

        // Click event for single list row
        list.setOnItemClickListener(new OnItemClickListener() {

            @SuppressWarnings("unchecked")
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {


                HashMap<String, String> o = (HashMap<String, String>) list.getItemAtPosition(position);
                Toast.makeText(CustomizedListView.this, "ID '" + o.get("KEY_TITLE") + "' was clicked.", Toast.LENGTH_SHORT).show(); 

            }
        });     
    }   
}

PHP 代码:

<?php

    $strno=$_GET['strno'];

    if (isset($strno))
    {
            $connect=mysql_connect("localhost","test","test") or die ('Connection error!!!');
            mysql_select_db("test") or die ('Database error!!!');

        $query=mysql_query("select sno FROM users  where strno='$strno';");
        while($row = mysql_fetch_assoc($query))

        {
            $jsonoutput='{"json":{
                "image":"'.$row['image'].'",
"artist":"'.$row['artist'].'",
"name":"'.$row['name'].'"
                }}';
        }

    }

    echo trim($jsonoutput);
    mysql_close($connect) or die ('Unable to close connection-error!!!');
    }

    ?>

【问题讨论】:

    标签: php android security http


    【解决方案1】:

    尝试根据您的要求添加一些参数,例如时间

    http://example.com/getmsgs/strno=123&time=20130416130256&key=....
    

    但是

    key = md5('20130416130256' + 'secret_string');
    

    'secret_string' 是您的应用程序和服务器的秘密,第一个字符串的格式为 gmt 时间(年月日时分秒)

    在服务器端你可以测试时间(它必须像服务器时间)和测试密钥(它必须是正确的 md5)

    从侧面看可以是这样的:

    $strno = $_GET['strno'];
    $stime = $_GET['time'];
    $secret = 'secret_string';
    $skey = $_GET['key'];
    
    if( md5($stime . $secret) != $skey ) {
        die('Bad key');
    }
    
    $nCurTime = (int) gmdate('YmdHis');
    if( ($stime > $nCurTime) || ($stime < ($nCurTime - 20) ) ) {
        die('Bad time');
    }
    
    // your code here ...
    

    但我不知道如何使用函数 md5 和获取时间


    添加:

    一些 google 搜索 (android md5) 给出 md5():

    public static final String md5(final String s) {
    try {
        // Create MD5 Hash
        MessageDigest digest = java.security.MessageDigest
                .getInstance("MD5");
        digest.update(s.getBytes());
        byte messageDigest[] = digest.digest();
    
        // Create Hex String
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < messageDigest.length; i++) {
            String h = Integer.toHexString(0xFF & messageDigest[i]);
            while (h.length() < 2)
                h = "0" + h;
            hexString.append(h);
        }
        return hexString.toString();
    
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "";
    }
    

    并获得格林威治时间Getting GMT time with Android

    【讨论】:

    • 感谢您的回复。能否请您在 android 和 php 中编辑上面的代码。我仍然对解决方案感到困惑。它会很有帮助。
    • 再次感谢。您能否分享上述说明的任何链接/示例。如果我有其他疑问,我可以查看并回复您。
    • 由函数md5()生成的密钥。在您的 android 应用程序中,您必须像在 php 中那样花时间添加您的秘密字符串,然后使用 md5() 制作密钥字符串。如果您在 android 中没有任何哈希函数,您可以制作自己的函数。
    • 这只是时间间隔 (($stime &lt; ($nCurTime - 20)) - 请求可能需要一些时间,服务器上的时间与 android 设备上的时间不同。您可以使用 2 个条件:($stime &lt; ($nCurTime - 20) || ($stime &lt; ($nCurTime + 20)。关于secret_string - 是的,它在您的 serevr 和 android 应用程序中保持不变。
    • 密钥在创建 evry 请求期间生成。每个请求都使用这个时间的时间和密钥。您的问题中没有任何关于注册的信息。
    猜你喜欢
    • 1970-01-01
    • 2011-01-16
    • 2014-07-17
    • 2010-12-12
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    相关资源
    最近更新 更多