2012-04-23 42 views
5

Tôi đang cố gắng triển khai bộ mã hóa chuỗi đơn giản để làm xáo trộn một số phần của chuỗi URL (để ngăn chúng bị người dùng nhỡ). Tôi đang sử dụng mã gần giống với mẫu trong JCA guide, ngoại trừ:Tránh ngắt dòng trong chuỗi URL được mã hóa và mã hóa

  • sử dụng DES (giả sử đó là một chút nhanh hơn so với thuật toán AES, và đòi hỏi phải có một phím nhỏ hơn) và
  • Base64 en/giải mã chuỗi đảm bảo rằng nó vẫn an toàn cho một URL.

Vì lý do tôi không thể hiểu được, chuỗi đầu ra kết thúc bằng dấu ngắt dòng, mà tôi cho là sẽ không hoạt động. Tôi không thể tìm ra nguyên nhân gây ra điều này. Đề xuất về nội dung nào đó tương tự dễ dàng hơn hoặc gợi ý đến một số tài nguyên khác để đọc? Tôi đang tìm tất cả các tham chiếu mật mã trên đầu của tôi (và quá mức), nhưng việc triển khai ROT13 đơn giản sẽ không hoạt động vì tôi muốn xử lý một bộ ký tự lớn hơn (và không muốn lãng phí thời gian thực hiện một cái gì đó có khả năng có vấn đề với các ký tự tối nghĩa mà tôi không nghĩ đến).

mẫu đầu vào (không ngắt dòng):

http://maps.google.com/maps?q=kansas&hl=en&sll=42.358431,-71.059773&sspn=0.415552,0.718918&hnear=Kansas&t=m&z=7 

Sample Output (ngắt dòng như hình dưới đây):

GstikIiULcJSGEU2NWNTpyucSWUFENptYk4m5lD8RJl8l1CuspiuXiE9a07fUEAGM/tC7h0Vzus+ 
jAH6cT4Wtz2RUlBdGf8WtQxVDKZVOzKwi84eQh2kZT9T3KomlnPOu2owJ/2RAEvG+QuGem5UGw== 

đoạn mã hóa của tôi:

final Key key = new SecretKeySpec(seed.getBytes(), "DES"); 
final Cipher c = Cipher.getInstance("DES"); 
c.init(Cipher.ENCRYPT_MODE, key); 
final byte[] encVal = c.doFinal(s.getBytes()); 
return new BASE64Encoder().encode(encVal); 
+1

bạn đã cố gắng chỉ hoàn nguyên op mã hóa của mình và xem liệu nó hoạt động? – Snicolas

+0

Trường hợp nào mà lớp BASE64Encoder đến từ đâu? – leonbloy

+1

@leonbloy Tôi đã nhập sun.misc.BASE64Decoder, mà tôi đã tìm thấy nhờ [bài đăng này] (http://stackoverflow.com/questions/2267036/work-sun-misc-base64encoder-decoder-for-getting- byte) không phải là một ý tưởng hay. – milletron

Trả lời

7

Base64 thường mã hóa áp đặt một số dòng tối đa (chunk) và thêm dòng mới khi ne cessary. Bạn thường có thể cấu hình điều đó, nhưng điều đó phụ thuộc vào việc thực hiện bộ mã hóa cụ thể. Ví dụ: Ví dụ, lớp từ Apache Commons có thuộc tính linelength, đặt thành 0 (hoặc âm) sẽ tắt tính năng tách dòng.

BTW: Tôi đồng ý với câu trả lời khác trong DES đó hiện nay không được khuyến khích. Hơn nữa, bạn chỉ "làm xáo trộn" hay thực sự mã hóa? Ai có chìa khóa? Toàn bộ mọi thứ không có mùi rất tốt với tôi.

+0

Nó thực sự là obfuscating hơn mã hóa. Chỉ cần sử dụng một chuỗi được mã hóa cứng như một "khóa" trong lớp gọi (được chia sẻ bởi các servlet tạo và tiêu thụ các url bị làm xáo trộn). Cảm ơn cho linelength lead, cũng được chỉ ra bởi @Jerry Coffin – milletron

+0

Vì bộ mã hóa Apache Commons nói "... nó được mã hóa cứng chỉ mã hóa/giải mã các ký tự mã hóa tương thích với biểu đồ 127 ASCII thấp hơn", chiến thắng này ' t làm việc vì tôi có các nhân vật bên ngoài phạm vi này. Sẽ cần phải suy nghĩ lại cách tiếp cận này, tôi nghĩ. – milletron

+0

"điều này sẽ không hoạt động vì tôi có các ký tự ngoài phạm vi này": đọc cẩn thận: nó hoạt động với các ký tự bên ngoài ASCII, chỉ là mã hóa nhị phân không thể là utf-16, nhưng nó có thể là utf-8 hoặc iso-8859-1, vv – leonbloy

1

Mặc dù nó không liên quan đến câu hỏi thực tế của bạn, DES thường chậm hơn AES (ít nhất là trong phần mềm), vì vậy, trừ khi bạn thực sự cần phải giữ chiếc chìa khóa nhỏ, AES là gần như chắc chắn một lựa chọn tốt hơn.

Thứ hai, hoàn toàn bình thường khi mã hóa (DES hoặc AES) sẽ/sẽ tạo ra các ký tự dòng mới trong đầu ra của nó. Sản lượng đầu ra mà không có chúng sẽ hoàn toàn dựa vào bộ mã hóa base-64, vì vậy đó là nơi bạn cần phải xem xét rõ ràng.

Thật không ngạc nhiên khi thấy cơ sở 64 chèn ký tự dòng mới theo khoảng thời gian đều đặn trong đầu ra của nó. Việc sử dụng phổ biến nhất cho mã hóa base-64 là đưa dữ liệu thô vào một thứ gì đó giống như phần thân của email, nơi một dòng dài thực sự sẽ gây ra vấn đề. Để ngăn chặn điều đó, dữ liệu được chia thành nhiều phần, thường không quá 80 cột (và thường ít hơn một chút). Trong trường hợp này, các dòng mới nên được bỏ qua, tuy nhiên, vì vậy bạn sẽ có thể chỉ cần xóa chúng, nếu bộ nhớ phục vụ.

11

Chỉ cần thực hiện base64Str = base64Str.replaceAll("(?:\\r\\n|\\n\\r|\\n|\\r)", "") trên chuỗi được mã hóa.

Nó hoạt động tốt khi bạn cố gắng giải mã nó trở lại byte. Tôi đã thử nghiệm nó nhiều lần với các mảng byte được tạo ngẫu nhiên.Rõ ràng quá trình giải mã chỉ bỏ qua các dòng mới hoặc là chúng có mặt hay không. Tôi đã thử nghiệm "xác nhận hoạt động" này bằng cách sử dụng com.sun.org.apache.xml.internal.security.utils.Base64 Các bộ mã hóa khác không được kiểm tra.

+2

Câu trả lời này là siêu tuyệt vời, ước gì tôi có thể upvote 10 lần. –

+1

thực hành tốt hay không, ai đó nên bình luận, nhưng bạn đã cứu ngày của tôi Ông cảm ơn – dakait

+0

Tuyệt vời. Làm việc trên một util riêng nhanh chóng, và điều này đã cứu tôi khỏi phải dừng lại và đi tìm một bộ mã hóa Base64 bên thứ 3. – developerwjk

1

Từ đoạn mã hóa của VA ...

thay thế:

return new BASE64Encoder().encode(encVal); 

với:

return new android.util.Base64.encodeToString(encVal, Base64.NO_WRAP); 

để loại bỏ dòng-break ra khỏi kết quả của chúng tôi

import android.util.Base64; 

... 

return new BASE64.encodeToString(encVal, Base64.NO_WRAP); 
+0

Bạn có thể xây dựng câu trả lời của mình một chút không? –

+0

Từ đoạn mã hóa của VA, chúng tôi thay thế "return new BASE64Encoder(). Encode (encVal);" với "return new android.util.Base64.encodeToString (encVal, Base64.NO_WRAP);" để loại bỏ ngắt dòng khỏi kết quả của chúng tôi. – user2955935