Translate

2016年3月2日 星期三

Android TripleDES encrypt/decrypt - 3DES加密(ECB Mode)

3DES
簡述 3DES,也稱為3DESede或TripleDES,是三重數據加密,且可以逆推的一種演算方案。 1975年每果IBM公司成功研究並發布了DES加密演算法,但DES密码長度容易被暴力破解,通過對DES演算法進行改版,針對每個數據塊進行三次DES加密,也就是3DES加密演算法。 但由于3DES的演算法是公開的,所以演算法本身沒有秘密可言,主要依靠唯一密鑰來確保數據加密解密的安全。 有人可能會問,那3DES到底安不安全呢?!目前為止,還沒有人能破解3DES,所以你要是能破解它,就足以震驚整個資安界了……

JAVA Code:
 
public class DESedeCrypto{
  
    private static final String Algorithm = "DESede/ECB/NoPadding";
    private static final String PASSWORD_CRYPT_KEY = "your_key";

    public static byte[] encryptMode(byte[] src) {
        try {
            //生成密鑰
            SecretKeySpec deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm); 
            //實現加解密物件   
            Cipher c1 = Cipher.getInstance(Algorithm);    
            //初始化為加密模式
            c1.init(Cipher.ENCRYPT_MODE, deskey);    
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }

  public static byte[] decryptMode(byte[] src) {
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);    //初始化為解密模式
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }

    /**
     * 修正KEY長度,3DES的密鑰長度需為24Byte,不夠補0
     *
     * @param keyStr  原KEY
     * @return
     * @throws UnsupportedEncodingException
     */
    public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
        byte[] key = new byte[24];    //宣告一個24Byte的Key,初始值為0
        byte[] temp = keyStr.getBytes("UTF-8");    //將字串轉為位元陣列

        if (key.length > temp.length) {
            //如果原key不夠24Byte,則拷貝至原key長度
            System.arraycopy(temp, 0, key, 0, temp.length);
        } else {
            //如果原key大於24Byte,則拷貝至24Byte
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    }
}

MainActivity

 
public class MainActivity extends Activity {
    String text = "your_will_encrypto_text";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DESedeCrypto crypto = new DESedeCrypto();
        try {
            byte[] textEncode = crypto.encryptMode(text.getBytes("UTF-8"));
            System.out.println(Base64.encodeToString(textEncode, Base64.DEFAULT));
            byte[]  textDecode = crypto.decryptMode(textEncode);
            System.out.println(new String(textDecode));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

※ java.security.InvalidKeyException :通常是你的key長度不對

2015年12月11日 星期五

ORM Library of Android SQLite - greenDAO 使用方法

greenDAO是一個open surce 去幫助Android開發者存取SQLite。
SQLite 是一個很棒的嵌入式關聯資料庫,但是開發卻非常費工,寫SQL是非常乏味冗長的任務,則greenDAO幫開發者做到這些事情,讓開發者能更專注於專案上其他問題。

greenDAO的主要設計目的:

  1. 最高效能
  2. API簡單好使用
  3. 高度優畫Android
  4. 低記憶體消耗
  5. 低Library Size (小於100k)
生成檔執行步驟:
  1. 建立Java module。
  2. 步驟1建立的Java module的gradle匯入library。
  3. 建立新的java檔,編寫DBSchema。
  4. 執行並創造生成檔。
步驟1












  compile 'de.greenrobot:greendao-generator:2.1.0'  //步驟2


  
//步驟3
public class Mydaogenerator {
    public static void main(String[] args) {
        // DB版本號  ,  目標 package name
        Schema schema = new Schema(1, "tw.myself.oceanlin.dao");
        createTable(schema);
        generateDaoFiles(schema);
    }

    private static void createTable(Schema schema) {
        //Entity 對應一個 DB table
        Entity point = schema.addEntity("FunghiDialog");
        //add table column
        point.addIdProperty();
        point.addDateProperty("date").notNull();
        point.addStringProperty("text").notNull();
    }

    private static void generateDaoFiles(Schema schema) {
        try {
            DaoGenerator generator = new DaoGenerator();
            //建立到指定目錄
            generator.generateAll(schema, "../GCM_Test/app/src/main/java");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


步驟4









自動生成檔















2015年12月10日 星期四

Facebook Android SDK 4 串接(二) - 個人資訊及發文

繼上篇Facebook Android SDK 4 串接(一) - Login 取Token

拿到Token後,用來讀取個人資訊及發文。

個人資訊:
loginButton.setReadPermissions("user_birthday");
要讀取生日須先取得權限。
 ※權限表Permissions

GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() 
            {
                @Override
                public void onCompleted(JSONObject jsonObject, GraphResponse graphResponse) {
                    Log.d("Show", jsonObject.toString());                    
                }
            });
            Bundle parameters = new Bundle();
            parameters.putString("fields", "id,name,birthday,gender,link,picture");
            request.setParameters(parameters);
            request.executeAsync();

取得的JSON(因為個資我就用"*"替代):
{
  "id": "8995768600*****",
  "name": "林**",
  "birthday": "11/29/1991",
  "gender": "male",
  "link": "https://www.facebook.com/app_scoped_user_id/8995768600*****/",
  "picture": {
    "data": {
      "is_silhouette": false,
      "url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xat1/v/t1.0-1/p50x50/12107037_1222898491060696_69373362222982*****_n.jpg?oh=729d711562d4315ba7cd03e72da693f2&oe=56E7F4B2&__gda__=1457302430_b22f949093879b5ccc2fa7b251c286cc"
    }
  }
}
接下來就解JSON就可以取得個別資訊了。

設定大頭貼:
使用SDK元件呈現,也可用個人資訊的picture{url}來呈現,但像素較低。
<com.facebook.login.widget.ProfilePictureView
    android:id="@+id/selection_profile_pic"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"/>
profilePictureView = (ProfilePictureView) findViewById(R.id.selection_profile_pic);
profilePictureView.setCropped(true);
profilePictureView.setPresetSize(ProfilePictureView.NORMAL);
profilePictureView.setProfileId(id);


發文:
Facebook Android SDK4.0+則是用ShareDialog來取代發文。
Sharing on Android:https://developers.facebook.com/docs/sharing/android
我們直接來看Code吧!
這是最簡單的發文(純文字)。
ShareDialog shareDialog = new ShareDialog(MainActivity.this);
ShareLinkContent linkContent = new ShareLinkContent.Builder().build();
shareDialog.show(linkContent);










2015年12月9日 星期三

Facebook Android SDK 4 串接(一) - Login 取Token

註冊APP ID:
首先你需要一組facebook_app_id,請到https://developers.facebook.com/quickstarts/?platform=android申請
  1. 建立APP的專案名稱
  2. 輸入Package Name及Default Activity Class Name
  3. 輸入development and release key hashes (下面有教學)
  4. 加入Logger到你的APP
  5. 取得facebook_app_id
  6. 然後去你創建的Settings裡,把Single Sign On打開
如何取得key hashes:
  1. 產生Facebook Key Hash 需要使用到OpenSSL這個工具,可以先到OpenSSL for Windows下載Binaries Zip這個版本
  2. 把openssl-0.9.8h-1-bin\bin\openssl.exe複製到你的keystore位置
  3. 打開cmd,並指定位置至keystore位置。
  4. 根據下列指令取得key
  5. 回到註冊步驟3填入
※沒有執行步驟1、2則會出現'openssl' 不是內部或外部命令、可執行的程式或批次檔。
YOUR_RELEASE_KEY_ALIAS = 你的key名稱
YOUR_RELEASE_KEY_PATH = 你的key名稱.副檔名
keytool -exportcert -alias YOUR_RELEASE_KEY_ALIAS -keystore YOUR_RELEASE_KEY_PATH | openssl sha1 -binary | openssl base64
示意圖:

2015年12月7日 星期一

Google Cloud Messaging(GCM)-Android推播通知訊息註冊

註冊API Key:
如果要使用Google API,一定要先到Google Developers Console中拿到API Key。


圖1.建立專案
圖2.啟用GCM API

圖3.建立金鑰









圖4.取得API Key 圖5.取得專案ID









2015年12月3日 星期四

RecyclerView 使用方法



RecyclerView中提供了三種佈局管理器,分別是:

  • LinearLayoutManager(線性佈局,類似ListView)
  • GridLayoutManager(網格佈局)
  • StaggeredGridLayoutManager(瀑布流佈局)



Gradle:
compile 'com.android.support:recyclerview-v7:23.1.0'

Layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity">
    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recyclerView">
    </android.support.v7.widget.RecyclerView>
</RelativeLayout>

MainActivity:

mRecyclerView = (RecyclerView) this.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new GridLayoutManager(MainActivity.this,3));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new MyRecyclerAdapter(this,lists);
mRecyclerView.setAdapter(adapter);
取得RecylerView物件,設定佈局及adapter。
線性佈局:mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
網格佈局:mRecyclerView.setLayoutManager(new GridLayoutManager(this,3));
瀑布流佈局(直向):mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL));
設定項目動畫為預設:mRecyclerView.setItemAnimator(new DefaultItemAnimator());