2014年6月26日星期四

Install Redmine on Ubuntu

Redmine 2.4.2.stable
MySQL 5.5.37-0ubuntu0.14.04.1
Ubuntu 14.04 desktop i386

1. Update package in Ubuntu

This may take a little bit of time...

sudo apt-get update
sudo apt-get upgrade


2. Install MySQL

You may need to set a password to your mysql root during the installation.

sudo apt-get install mysql-server


3. Setup database and user for Redmine

CREATE DATABASE redmine CHARACTER SET utf8;
GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost' IDENTIFIED BY 'my_password';


4. Install Redmine

Redmine provides 3 choices, MySQL, PostgreSQL and SQL Server, of database. MySQL is picked here.

sudo apt-get install redmine redmine-mysql


5. Config database settings

The database.yml is located under /etc/redmine/default. Edit it by vim.

sudo vim /etc/redmine/default/database.yml


The contents of database.yml file look like followings after edited.

production:
  adapter: mysql
  database: redmine
  host: localhost
  port:
  username: redmine
  password: my_password
  endcoding: utf8

The Redmine website suggests mysql2 adapter using ruby 1.9. But it works fine with mysql adapter in my case. You can specify another port number here. Username, password, database and endcoding should be the same as those when you setup database for Redmine.

6. Create database schema objects

Go to Redmine application root directory.

cd /usr/share/redmine


Run following command

RAILS_ENV=production rake db:migrate


Run following command to set default data (I skip this step. It doesn't make anything wrong after Redmine was started)

RAILS_ENV=production rake redmine:load_default_data


7. Config log settings

Make a log folder

sudo mkdir /usr/share/redmine/log


Edit production.rb file

sudo vim /usr/share/redmine/config/environments/production.rb


Add followings codes to specify the log file name, location and log level

config.logger = Logger.new('/usr/share/redmine/log/production.log', 7, 1048576)
config.logger.level = Logger::INFO


8. Start WEBrick to run application

Let's use WEBrick to run Redmine. Enter following command to start WEBrick.

sudo ruby /usr/share/redmine/script/rails server -e production


Try it at 

http://localhost:3000



2014年1月21日星期二

RSA加密

這次需求是把用戶在網頁上輸入的文字加密送至後台解密。
  • 使用RSA演算法。
  • Key長度為2048bits。
  • 前台使用Javascript。
  • 後台使用Java。

首先產生加密解密時使用的Private Key及Public Key。
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4));

KeyPair kp = kpg.genKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
               
RSAPublicKeySpec pub = (RSAPublicKeySpec) fact.getKeySpec(publicKey, RSAPublicKeySpec.class);
BigInteger modulus = pub.getModulus();
System.out.println(modulus.toString(16));
System.out.println(Utils.byteArrayToBase64String(publicKey().getEncoded()));
System.out.println(Utils.byteArrayToBase64String(privateKey().getEncoded()));
Modulus
008FFAF9E528760E1B31324FC11D2ED0291589630D1F1FC954E67A2A82D28CA4BEAC2A41AACBBFB37F3E77A7C31F7AEC3D7A33699FB6C6D6E3AD2826702A5DAB928FBDEAB79EBB64287C56C4896ECC912D2FE831B8900B81F1653DA3DA2D1FE47E454456CAB9C877ED48BDD2C376E7AF82E620414CC2A019D0D7D01C0C2CD108C

Public Key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCP+vnlKHYOGzEyT8EdLtApFYljDR8fyVTmeiqC0oykvqwqQarLv7N/Pnenwx967D16M2mftsbW460oJnAqXauSj73qt567ZCh8VsSJbsyRLS/oMbiQC4HxZT2j2i0f5H5FRFbKuch37Ui90sN256+C5iBBTMKgGdDX0BwMLNEIwwIDAQAB
-----END PUBLIC KEY-----
Private Key
-----BEGIN RSA PRIVATE KEY-----MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI/6+eUodg4bMTJPwR0u0CkViWMNHx/JVOZ6KoLSjKS+rCpBqsu/s38+d6fDH3rsPXozaZ+2xtbjrSgmcCpdq5KPveq3nrtkKHxWxIluzJEtL+gxuJALgfFlPaPaLR/kfkVEVsq5yHftSL3Sw3bnr4LmIEFMwqAZ0NfQHAws0QjDAgMBAAECgYAu9i2MESZwc24YeusCGcLLo7qsFBuSwphulGpJQWOeWJLPNZv/2Qcy+a0Nixc5gNSMhzhsX7F7ZceU0PTE3MiZB/+AW9ZIB5g8Yn9wlcugBfVpC9KtD4jEydLi00yhuKLEttKfrcEKRo4irl30e81RHVMhK3rBGsjmJUFUN1dcAQJBAMVVfGQRZR+pfuaMo5kOX8Ir09USkmDZ+0t+s9QeUtNKNWY9NFntfZnaaFVLvfzofe3KzLc+wJRKCKjgRuLRO38CQQC6yOfeAvGAqRkYH+ilgDsr6LC01+V/FtsNMufm1K5YblhgHq7lmGQB5KR6ZOjlY/2PqQSyTnP1T5zHuAQ6JeS9AkEAkLN78IEU7x/CD1tHx79TlrW+svrYXa7aZ+S0BzJpN8it2Ze94MeWl5Ahe5J78Y2mcg2JCkI4w0R6jyNOt5oIDwJAZ8hFfQfpo/FQ7iScoYiUWBtcQ79J1smeQMEuNQWrMZtuI0opJ4z61Ep0UUVMWliqhG4HHAOXTpBDrnzCbIStiQJAWvGE4DSlHYEsDnJTCfpEg7b8XGijMVIGOUG1JYqA+bjcq/+RfOCCJy5tsBlLw+BvG2mFispJ3PY7t4w9dhk8NQ==
-----END RSA PRIVATE KEY-----

頁面的Javascript加密方式使用Tom Wu提供的Demo作示範。

  • 在Plaintext輸入需加密的文字This is a test!
  • 在Public exponent (hex, F4=0x10001):輸入10001
  • 在Modulus (hex):輸入 008FFAF9E528760E1B31324FC11D2ED0291589630D1F1FC954E67A2A82D28CA4BEAC2A41AACBBFB37F3E77A7C31F7AEC3D7A33699FB6C6D6E3AD2826702A5DAB928FBDEAB79EBB64287C56C4896ECC912D2FE831B8900B81F1653DA3DA2D1FE47E454456CAB9C877ED48BDD2C376E7AF82E620414CC2A019D0D7D01C0C2CD108C
  • 按Encrypt得到加密後的值(base64)。(例︰  Y0OOWkCHB8HXOv1J7DbBSp1TGEiuR58AxqewXbjH1FTGJ9c2n/czN8/y1FDfxrpdNvIRyPL8B6nePqyL5xvp+VJUUfEGmYpOQy4oMh6S0lJB01yJwyHkznZSaaO1WFPRjC8xbq02FSRNBvjlFAeHGrUC7WxrqnBMKPintDC7weY=)

後台得到加密後文字進行解密
String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI/6+eUodg4bMTJPwR0u0CkViWMNHx/JVOZ6KoLSjKS+rCpBqsu/s38+d6fDH3rsPXozaZ+2xtbjrSgmcCpdq5KPveq3nrtkKHxWxIluzJEtL+gxuJALgfFlPaPaLR/kfkVEVsq5yHftSL3Sw3bnr4LmIEFMwqAZ0NfQHAws0QjDAgMBAAECgYAu9i2MESZwc24YeusCGcLLo7qsFBuSwphulGpJQWOeWJLPNZv/2Qcy+a0Nixc5gNSMhzhsX7F7ZceU0PTE3MiZB/+AW9ZIB5g8Yn9wlcugBfVpC9KtD4jEydLi00yhuKLEttKfrcEKRo4irl30e81RHVMhK3rBGsjmJUFUN1dcAQJBAMVVfGQRZR+pfuaMo5kOX8Ir09USkmDZ+0t+s9QeUtNKNWY9NFntfZnaaFVLvfzofe3KzLc+wJRKCKjgRuLRO38CQQC6yOfeAvGAqRkYH+ilgDsr6LC01+V/FtsNMufm1K5YblhgHq7lmGQB5KR6ZOjlY/2PqQSyTnP1T5zHuAQ6JeS9AkEAkLN78IEU7x/CD1tHx79TlrW+svrYXa7aZ+S0BzJpN8it2Ze94MeWl5Ahe5J78Y2mcg2JCkI4w0R6jyNOt5oIDwJAZ8hFfQfpo/FQ7iScoYiUWBtcQ79J1smeQMEuNQWrMZtuI0opJ4z61Ep0UUVMWliqhG4HHAOXTpBDrnzCbIStiQJAWvGE4DSlHYEsDnJTCfpEg7b8XGijMVIGOUG1JYqA+bjcq/+RfOCCJy5tsBlLw+BvG2mFispJ3PY7t4w9dhk8NQ=="

// don't use this for real projects!
BASE64Decoder decoder = new BASE64Decoder();
keyBytes = decoder.decodeBuffer(priKey);

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(spec);

Cipher cipher = Cipher.getInstance("RSA");
byte[] dec = Utils.base64StringToByteArray(ciphertext);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decrypted = cipher.doFinal(dec);
System.out.println(new String(decrypted, "UTF-8"));
解密結果
This is a test!

使用OpenSSL檢視PublicKey.pem及PrivateKey.pem
openssl rsa -in public.pem -pubin -text -noout
openssl rsa -in private.pem -text -noout
openssl rsa -in private.pem -modulus -noout

參考連結
http://www-cs-students.stanford.edu/~tjw/jsbn/
http://cryptojs.altervista.org/
http://cryptojs.altervista.org/publickey/doc/doc_rsa_java.html

2013年11月8日星期五

上車攻略(14):上車,把握有時機法

轉載文章,原文摘自筆與誌評

就算儲足首期,做定功課, 並不代表可以上車,在不適當的時候「上錯車」,隨時要守很多年都未見家鄉。 大家到地產網站查一查成交紀錄,那些1997年買入的單位, 就算不用蝕錢離場,都賺不了多少錢。最慘的是長期坐艇,想換樓都要貼好多錢,人生有幾多個十年,這樣又錯過了一個浪。 所以筆者要介紹怎樣衡量是否入市時機,以便輕鬆上車
1. 樓市估值有數得計
最理想的入市時機,當然係最低位入,不過可遇不可求;退而求其次就是避免在樓價偏高時買入。衡量樓價有很多指標,例如供款負擔比率、樓價收入比、租金回報率等,不過不容易獲得最新數據,幾個月前的數據實用性大打折扣。
最簡單直接的方法,就是自行計算樓價與租金的比率,即租價比(Price-Rent Ratio) 。美聯樓價走勢每個月都提供全港的平均樓價及平均租金,那就可以自己計算,算式是:
20111124A
根據美聯網站,九月份平均樓價是5,838元,平均租金是20.92元,一計就知道租價比是4.3%,算平還算貴呢?筆者就將1996年以來相關數據製成圖表,大家可以看到上一次低到4%是1997年時,筆者就認為要等到租價比升回5%以上才值得入市。
20111124
2. 賭檯之上莊話事
誰人是樓市的最終話事人?不要以為是發展商,政府真的有心干預市場,除了操縱土地供應外,更會連同金管局控制銀行放貸。眼前就是典型例子:政府每個月都拋出土地,樓市即時淡靜;金管局要求銀行謹慎借出按揭,銀行就提高按息、收緊按揭比率、降低物業估值。就算想入市,都不易借得足錢。
所以適合入市的時機,應該是政府收緊供應,金管局放寬對銀行的管制,銀行又開始放水出街。對上一次發生是2009年初:停止賣地、可以借到九五按、銀行降息搶客、連收租物業都可以借二按!這種情況未來都會發生,大家要多加留意。
3. 發展商收起優惠
新樓往往比二手樓貴,不過發展商在市況欠佳時,都會提供優惠條款來吸引買家。旺市時即供價就是原價,入伙才付款就要加錢;淡市時就會反其道而行,即供就有折扣。雖然明知這是數字遊戲,但是都是發展商的表態,究竟是買家市場還是賣家市場。
不過更為實質的是發展商提供二按,或者用現金回贈的方式降低首期,鼓勵買家入市,以前甚至試過買家碌咭支付10%首期,發展商就提供10%回贈,變相零首期買樓,這便是強烈地表示後市還有得跌。當發展商漸漸收回這些優惠時,才是穩陣的入市訊號。
4. 要有逆市而行的思維
樓市偏軟已成定局,猶記得這兩年來傳媒鋪天蓋地推出「樓市訴苦」節目,找來多個苦主說上不到車,又或要求政復建居屋;而在樓價開始下跌,居屋又決定復建,要求上車的聲音幾乎消失。
股市的相反理論認為,當擦鞋工人都在談論股票時,股市會見頂;當血灑街頭時人人都避談股票才是入市時機。當人人都話要上車,或者怨好難上車,應該都係樓價比較高的時候,如果抱著人有我有的心態,就最容易中招。相反金融海嘯時,連抽中居屋都大把人放飛機不現身揀樓,往往就係樓價見底之時。
買樓是你自己的事,無需要諮詢其他人的意見,不過仍然有好多人走去問家人朋友,根據筆者的親身經驗,不是無稜兩可就是過於保守,就算問都不宜無條件接受。